Re: Performance drop due to alloc_workqueue() misuse and recent change

2023-12-19 Thread Tejun Heo
Hello, again.

On Mon, Dec 04, 2023 at 04:03:47PM +, Naohiro Aota wrote:
...
> In summary, we misuse max_active, considering it is a global limit. And,
> the recent commit introduced a huge performance drop in some cases.  We
> need to review alloc_workqueue() usage to check if its max_active setting
> is proper or not.

Can you please test the following branch?

 https://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git 
unbound-system-wide-max_active

Thanks.

-- 
tejun


Re: [PATCH 4/5] clk: sunxi-ng: a64: Add constraints on PLL-VIDEO0's n/m ratio

2023-12-19 Thread Frank Oltmanns


On 2023-12-19 at 17:54:19 +0100, Jernej Škrabec  
wrote:
> Dne ponedeljek, 18. december 2023 ob 14:35:22 CET je Frank Oltmanns 
> napisal(a):
>> The Allwinner A64 manual lists the following constraint for the
>> PLL-VIDEO0 clock: 8 <= N/M <= 25
>>
>> Use this constraint.
>>
>> Signed-off-by: Frank Oltmanns 
>> ---
>>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 8 ++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c 
>> b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
>> index c034ac027d1c..75d839da446c 100644
>> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
>> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
>> @@ -68,7 +68,8 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, 
>> "pll-audio-base",
>> BIT(28), /* lock */
>> CLK_SET_RATE_UNGATE);
>>
>> -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, 
>> "pll-video0",
>> +static 
>> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT_NM_RATIO(pll_video0_clk,
>> +"pll-video0",
>>  "osc24M", 0x010,
>>  19200,  /* Minimum rate 
>> */
>>  100800, /* Maximum rate 
>> */
>> @@ -80,7 +81,10 @@ static 
>> SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, "pll-vid
>>  29700,  /* frac rate 1 
>> */
>>  BIT(31),/* gate */
>>  BIT(28),/* lock */
>> -CLK_SET_RATE_UNGATE);
>> +CLK_SET_RATE_UNGATE,
>> +CCU_FEATURE_FRACTIONAL |
>> +CCU_FEATURE_CLOSEST_RATE,
>
> Above flags are unrelated change, put them in new patch if needed.

You might notice that I am using a new macro for initializing the
pll_video0_clk struct:
New: SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT_NM_RATIO
Old: SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST

Setting the two CCU_FEATURE flags is part of the old initialization
macro.

I'll add SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_NM_RATIO_CLOSEST which
hopefully resolves the confusion.

Thanks,
  Frank

>
> Best regards,
> Jernej
>
>> +8, 25); /* min/max nm 
>> ratio */
>>
>>  static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
>>  "osc24M", 0x018,
>>
>>


Re: [PATCH 1/5] clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate

2023-12-19 Thread Frank Oltmanns
Hi Jernej!

On 2023-12-19 at 17:46:08 +0100, Jernej Škrabec  
wrote:
> Hi Frank!
>
> Dne ponedeljek, 18. december 2023 ob 14:35:19 CET je Frank Oltmanns 
> napisal(a):
>> The Allwinner A64 manual lists the following constraints for the
>> PLL-MIPI clock:
>>  - M/N >= 3
>
> This should be "<="

Yes, good catch! I will fix it in V2.

>
>>  - (PLL_VIDEO0)/M >= 24MHz
>>
>> The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for
>> these constraints.
>>
>> Signed-off-by: Frank Oltmanns 
>> ---
>>  drivers/clk/sunxi-ng/ccu_nkm.c | 23 +++
>>  drivers/clk/sunxi-ng/ccu_nkm.h |  8 
>>  2 files changed, 31 insertions(+)
>>
>> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
>> index eed64547ad42..2af5c1ebd527 100644
>> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
>> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
>> @@ -16,6 +16,20 @@ struct _ccu_nkm {
>>  unsigned long   m, min_m, max_m;
>>  };
>>
>> +static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned long 
>> parent,
>> +  unsigned long n, unsigned long m)
>> +{
>> +struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);
>> +
>> +if (nkm->max_mn_ratio && (m > nkm->max_mn_ratio * n))
>> +return false;
>> +
>> +if (nkm->parent_wo_nk && (parent < nkm->parent_wo_nk * m))
>> +return false;
>> +
>> +return true;
>> +}
>> +
>>  static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common 
>> *common,
>> struct clk_hw *parent_hw,
>> unsigned long *parent, 
>> unsigned long rate,
>> @@ -32,6 +46,9 @@ static unsigned long 
>> ccu_nkm_find_best_with_parent_adj(struct ccu_common *common
>>
>>  tmp_parent = clk_hw_round_rate(parent_hw, rate 
>> * _m / (_n * _k));
>>
>> +if (!ccu_nkm_is_valid_rate(common, tmp_parent, 
>> _n, _m))
>> +continue;
>> +
>>  tmp_rate = tmp_parent * _n * _k / _m;
>>
>>  if (ccu_is_better_rate(common, rate, tmp_rate, 
>> best_rate) ||
>> @@ -65,6 +82,12 @@ static unsigned long ccu_nkm_find_best(unsigned long 
>> parent, unsigned long rate,
>>  for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
>>  for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
>>  for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
>> +if ((common->reg == 0x040) && (_m > 3 * _n))
>> +break;
>> +
>> +if ((common->reg == 0x040) && (parent < 
>> 2400 * _m))
>> +continue;
>> +
>
> You already figured this part.
>
>>  unsigned long tmp_rate;
>>
>>  tmp_rate = parent * _n * _k / _m;
>> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
>> index 6601defb3f38..d3d3eaf55faf 100644
>> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
>> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
>> @@ -16,6 +16,12 @@
>>   * struct ccu_nkm - Definition of an N-K-M clock
>>   *
>>   * Clocks based on the formula parent * N * K / M
>> + *
>> + * @max_mn_ratio:   Maximum value for M / N.
>> + * @parent_wo_nk:   The minimum rate the parent must provide after applying 
>> the divisor,
>> + *  but without applying the multipliers, i.e. the 
>> contstraint
>> + * (parent rate)/M >= parent_wo_nk
>> + *  must be fulfilled.
>>   */
>>  struct ccu_nkm {
>>  u32 enable;
>> @@ -27,6 +33,8 @@ struct ccu_nkm {
>>  struct ccu_mux_internal mux;
>>
>>  unsigned intfixed_post_div;
>> +unsigned long   max_mn_ratio;
>> +unsigned long   parent_wo_nk;
>
> What about max_m_n_ratio and max_parent_m_ratio, to be consistent? This
> should also allow to simplify description.

Jernej, thank you so much! This is brilliant! I was racking my brain for
a good name but failed. Now, that I see your proposal, I don't know why
I hadn't come up with it. It's the obvious choice.

I'd say with the new names we should be able to get rid of the comments
describing the new struct members (also in ccu_nm.h). What are your
thoughts on that?

Best regards,
  Frank

>
> Best regards,
> Jernej
>
>>
>>  struct ccu_common   common;
>>  };
>>
>>


Re: [PATCH 6/7] accel/qaic: Leverage DRM managed APIs to release resources

2023-12-19 Thread Jacek Lawrynowicz
On 15.12.2023 19:06, Jeffrey Hugo wrote:
> On 12/8/2023 9:34 AM, Jeffrey Hugo wrote:
>> From: Pranjal Ramajor Asha Kanojiya 
>>
>> Offload the balancing of init and destroy calls to DRM managed APIs.
>> mutex destroy for ->cntl_mutex is not called during device release and
>> destroy workqueue is not called in error path of create_qdev(). So, use
>> DRM managed APIs to manage the release of resources and avoid such
>> problems.
>>
>> Signed-off-by: Pranjal Ramajor Asha Kanojiya 
>> Reviewed-by: Jeffrey Hugo 
>> Signed-off-by: Jeffrey Hugo 
> 
> Jacek, I saw a review from you for 1-5, and 7 but not this patch (6). Did I 
> miss something?

Sorry, I was out of office for a couple days and I wasn't able to finish the 
review.

Reviewed-by: Jacek Lawrynowicz 


Re: [PATCH 01/27] sparc32: Update defconfig to LEON SMP

2023-12-19 Thread Sam Ravnborg
Hi Arnd,

On Tue, Dec 19, 2023 at 10:23:05PM +, Arnd Bergmann wrote:
> On Tue, Dec 19, 2023, at 22:03, Sam Ravnborg via B4 Relay wrote:
> > From: Sam Ravnborg 
> >
> > This is a copy of the leon_smp defconfig found in
> > gaisler-buildroot-2023.02-1.0.
> >
> > Signed-off-by: Sam Ravnborg 
> > Cc: "David S. Miller" 
> > Cc: Arnd Bergmann 
> > Cc: Andreas Larsson 
> 
> I did not get a cover letter for the series, but I looked at
You are listed as a receiver?!?

It can be found here:
https://lore.kernel.org/sparclinux/20231219-sam-sparc32-sunset-v3-v1-0-64bb44b59...@ravnborg.org/T/#m2fc5b3c23331efd12492a61ba39ac000a563ac52

> all 27 patches and they all look good to me, nice cleanup!
> 
> Acked-by: Arnd Bergmann 
Thanks!

Sam


Re: [PATCH 24/27] sparc32: Drop config SPARC_LEON

2023-12-19 Thread Greg Kroah-Hartman
On Tue, Dec 19, 2023 at 11:03:29PM +0100, Sam Ravnborg via B4 Relay wrote:
> From: Sam Ravnborg 
> 
> The only support sparc32 CPU is LEON, so there is no need for a
> config option to select it.
> 
> Signed-off-by: Sam Ravnborg 
> Cc: "David S. Miller" 
> Cc: Arnd Bergmann 
> Cc: Andreas Larsson 

For the USB stuff:

Acked-by: Greg Kroah-Hartman 


Re: [PATCH v3 2/6] x86/vmware: Introduce vmware_hypercall API

2023-12-19 Thread Alexey Makhalov




On 12/19/23 4:51 PM, kirill.shute...@linux.intel.com wrote:

On Tue, Dec 19, 2023 at 04:17:40PM -0800, Alexey Makhalov wrote:



On 12/19/23 3:20 PM, kirill.shute...@linux.intel.com wrote:

On Tue, Dec 19, 2023 at 01:57:47PM -0800, Alexey Makhalov wrote:

+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)

...

+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2)

...

+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2,
+   uint32_t *out3)

...

+static inline
+unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
+   unsigned long in3, unsigned long in4,
+   unsigned long in5, uint32_t *out2)

...

+static inline
+unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
+   unsigned long in3, uint32_t *out2,
+   uint32_t *out3, uint32_t *out4,
+   uint32_t *out5)

...

+static inline
+unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
+   unsigned long in3, unsigned long in4,
+   unsigned long in5, uint32_t *out1,
+   uint32_t *out2, uint32_t *out3)


Naming is weird. The number in the name doesn't help much as there seems
no system on how many of the parameters are ins and outs.


There was internal discussion on hypercall API naming. One of proposals was
using 2 digits - number of input and number of output arguments.
And it definitely looked weird. So, we agreed to have just single number  -
total number of arguments excluding cmd.


Have you considered naming them by number of input parameters? Number of
output parameters as demanded by users.

So vmware_hypercall4() will become vmware_hypercall1() and current
vmware_hypercall1() and vmware_hypercall3() will go away.

It is still awful, but /maybe/ better that this, I donno.



Deprecating vmware_hypercall1 and vmware_hypercall3 in favor of 
vmware_hypercall4 will generate less efficient code for the caller of 
first ones.
Using current vmware_hypercall4 instead of vmware_hypercall1 will force 
the caller to allocate additional variables (register or on stack 
memory) for hypercall asm inline to put additional output registers on. 
And specifically to 'usage' of *out3 - compiler will unnecessary 
'clobber' useful rdx, when hypervisor will keep it unchanged.


Unfortunately VMware hypercall ABI is not as beautiful as KVM one, 
especially in number of output arguments and their ordering. rbp 
register usage as an argument is a separate bummer((. So we have to work 
with what we have.


Current set of functions includes only 6 functions (for LB), which is 
the optimum between readability, maintainability and performance. It 
covers all current kernel callers and all new callers from yet to be 
upstreamed patches that we have in Photon OS including 2 patches for x86 
and arm64 guest support.


Regards,
--Alexey


Re: [PATCH v3 6/6] x86/vmware: Add TDX hypercall support

2023-12-19 Thread Alexey Makhalov




On 12/19/23 5:00 PM, kirill.shute...@linux.intel.com wrote:

On Tue, Dec 19, 2023 at 04:27:51PM -0800, Alexey Makhalov wrote:



On 12/19/23 3:23 PM, kirill.shute...@linux.intel.com wrote:

On Tue, Dec 19, 2023 at 01:57:51PM -0800, Alexey Makhalov wrote:

diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 3aa1adaed18f..ef07ab7a07e1 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -428,6 +428,30 @@ static bool __init vmware_legacy_x2apic_available(void)
(eax & BIT(VCPU_LEGACY_X2APIC));
   }
+#ifdef CONFIG_INTEL_TDX_GUEST
+unsigned long vmware_tdx_hypercall(unsigned long cmd,
+  struct tdx_module_args *args)
+{
+   if (!hypervisor_is_type(X86_HYPER_VMWARE))
+   return 0;


BTW, don't you want to warn here to? We don't expect vmware hypercalls to
be called by non-vmware guest, do we?


The answer is below...




+
+   if (cmd & ~VMWARE_CMD_MASK) {
+   pr_warn("Out of range command %x\n", cmd);
+   return 0;


Is zero success? Shouldn't it be an error?


VMware hypercalls do not have a standard way of signalling an error.
To generalize expectations from the caller perspective of any existing
hypercalls: error (including hypercall is not supported or disabled) is when
return value is 0 and out1/2 are unchanged or equal to in1/in2.


You are talking about signaling errors over hypercall transport. But if
kernel can see that something is wrong why cannot it signal the issue
clearly to caller. It is going to be in-kernel convention.These "return 0" blocks were introduced to protect against non-vmware 
guest or arbitrary modules trying to use __tdx_hypercall via exported 
vmware_tdx_hypercall function. In this case, it will be NOOP behavior 
with no or minor side effects.


From valid vmware_hypercall callers point of view, there is no such 
thing as a hypercall not available. Once guest detection code recognizes 
VMWare hypervisor via cpuid, it will start using hypercalls in 
accordance to per-call API.


Valid VMware guest code will never go into first return, no warning 
required.
Second return can be hit in rare cases for example during development 
phase, or, hypothetical case, when cmd was dynamically generated.

That's why we have a warning warning only for the second condition.

While speaking about it, I'm started to lean towards your 
recommendation. Yes, we can return standard error code such as -EINVAL 
or just -1 instead of "return 0" in this function. And it will be 
algorithmically correct. As if Vmware guest caller provide out of range 
cmd - it is not documented behavior.


Speaking of additional in-kernel convention for passing additional 
parameter if error happens, it does not makes sense for me because:
1. existing caller codes analyze output argument to recognize error 
error response from the hypervisor. Adding one additional check for 
in-kernel errors just for TDX path which will be never hit by valid code 
in production is an unnecessary overhead.
2. It will definitely add an overhead as an error code will require one 
more output value, or out0 should be moved from return in-register value 
to return by pointer function argument.


Summarizing, overloading vmware_tdx_hypercall return value by arg0 (from 
the hypervisor) and kernel error (-1 or any other) seems like reasonable 
change.




And to very least, it has to be pr_warn_once().


Good catch! Will change it.

Thanks,
--Alexey


[PATCH linux-next] drm/panel: Simplify with dev_err_probe()

2023-12-19 Thread yang.guang5
From: Yang Guang 

dev_err_probe() can check if the error code is -EPROBE_DEFER 
and can return the error code, replacing dev_err() with it 
simplifies the code.

Signed-off-by: Chen Haonan 
---
 drivers/gpu/drm/panel/panel-boe-himax8279d.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-himax8279d.c 
b/drivers/gpu/drm/panel/panel-boe-himax8279d.c
index 11b64acbe8a9..e225840b0d67 100644
--- a/drivers/gpu/drm/panel/panel-boe-himax8279d.c
+++ b/drivers/gpu/drm/panel/panel-boe-himax8279d.c
@@ -854,26 +854,20 @@ static int panel_add(struct panel_info *pinfo)

pinfo->pp18_gpio = devm_gpiod_get(dev, "pp18", GPIOD_OUT_HIGH);
if (IS_ERR(pinfo->pp18_gpio)) {
-   ret = PTR_ERR(pinfo->pp18_gpio);
-   if (ret != -EPROBE_DEFER)
-   dev_err(dev, "failed to get pp18 gpio: %d\n", ret);
-   return ret;
+   return dev_err_probe(dev, PTR_ERR(pinfo->pp18_gpio),
+"failed to get pp18 
gpio\n");
}

pinfo->pp33_gpio = devm_gpiod_get(dev, "pp33", GPIOD_OUT_HIGH);
if (IS_ERR(pinfo->pp33_gpio)) {
-   ret = PTR_ERR(pinfo->pp33_gpio);
-   if (ret != -EPROBE_DEFER)
-   dev_err(dev, "failed to get pp33 gpio: %d\n", ret);
-   return ret;
+   return  dev_err_probe(dev, PTR_ERR(pinfo->pp33_gpio),
+"failed to get pp33 
gpio\n");
}

pinfo->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
if (IS_ERR(pinfo->enable_gpio)) {
-   ret = PTR_ERR(pinfo->enable_gpio);
-   if (ret != -EPROBE_DEFER)
-   dev_err(dev, "failed to get enable gpio: %d\n", ret);
-   return ret;
+   return  dev_err_probe(dev, PTR_ERR(pinfo->enable_gpio),
+"failed to get enable gpio\n");
}

drm_panel_init(>base, dev, _funcs,
-- 
2.25.1


[PATCH linux-next] drm/amd/display: use kcalloc instead of open coded arithmetic

2023-12-19 Thread yang.guang5
From: Yang Guang 

Dynamic size calculations (especially multiplication) should not be 
performed in memory allocator (or similar) function arguments due 
to the risk of them overflowing. This could lead to values wrapping 
around and a smaller allocation being made than the caller was 
expecting. Using those allocations could lead to linear overflows 
of heap memory and other misbehaviors. 

Signed-off-by: Chen Haonan 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index d7ac020bd8af..d6d63bd7482e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9204,7 +9204,7 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
 * Here we create an empty update on each plane.
 * To fix this, DC should permit updating only stream 
properties.
 */
-   dummy_updates = kzalloc(sizeof(struct dc_surface_update) * 
MAX_SURFACES, GFP_ATOMIC);
+   dummy_updates = kcalloc(MAX_SURFACES, sizeof(struct 
dc_surface_update), GFP_ATOMIC);
for (j = 0; j < status->plane_count; j++)
dummy_updates[j].surface = status->plane_states[0];

-- 
2.25.1


Re: [RFC PATCH] KVM: Introduce KVM VIRTIO device

2023-12-19 Thread Yan Zhao
On Tue, Dec 19, 2023 at 12:26:45PM +0800, Yan Zhao wrote:
> On Mon, Dec 18, 2023 at 07:08:51AM -0800, Sean Christopherson wrote:
> > > > Implementation Consideration
> > > > ===
> > > > There is a previous series [1] from google to serve the same purpose to
> > > > let KVM be aware of virtio GPU's noncoherent DMA status. That series
> > > > requires a new memslot flag, and special memslots in user space.
> > > > 
> > > > We don't choose to use memslot flag to request honoring guest memory
> > > > type.
> > > 
> > > memslot flag has the potential to restrict the impact e.g. when using
> > > clflush-before-read in migration?
> > 
> > Yep, exactly.  E.g. if KVM needs to ensure coherency when freeing memory 
> > back to
> > the host kernel, then the memslot flag will allow for a much more targeted
> > operation.
> > 
> > > Of course the implication is to honor guest type only for the selected 
> > > slot
> > > in KVM instead of applying to the entire guest memory as in previous 
> > > series
> > > (which selects this way because vmx_get_mt_mask() is in perf-critical path
> > > hence not good to check memslot flag?)
> > 
> > Checking a memslot flag won't impact performance.  KVM already has the 
> > memslot
> > when creating SPTEs, e.g. the sole caller of vmx_get_mt_mask(), 
> > make_spte(), has
> > access to the memslot.
> > 
> > That isn't coincidental, KVM _must_ have the memslot to construct the SPTE, 
> > e.g.
> > to retrieve the associated PFN, update write-tracking for shadow pages, etc.
> > 
> Hi Sean,
> Do you prefer to introduce a memslot flag KVM_MEM_DMA or KVM_MEM_WC?
> For KVM_MEM_DMA, KVM needs to
> (a) search VMA for vma->vm_page_prot and convert it to page cache mode (with
> pgprot2cachemode()? ), or
> (b) look up memtype of the PFN, by calling lookup_memtype(), similar to that 
> in
> pat_pfn_immune_to_uc_mtrr().
> 
> But pgprot2cachemode() and lookup_memtype() are not exported by x86 code now.
> 
> For KVM_MEM_WC, it requires user to ensure the memory is actually mapped
> to WC, right?
> 
> Then, vmx_get_mt_mask() just ignores guest PAT and programs host PAT as EPT 
> type
> for the special memslot only, as below.
> Is this understanding correct?
> 
> static u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
> {
> if (is_mmio)  
>  
> return MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT; 
>  
>   
>  
> if (gfn_in_dma_slot(vcpu->kvm, gfn)) {
>  
> u8 type = MTRR_TYPE_WRCOMB;   
>
> //u8 type = pat_pfn_memtype(pfn); 
>
> return (type << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;
>
> } 
>  
>   
>  
> if (!kvm_arch_has_noncoherent_dma(vcpu->kvm)) 
>
> return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | 
> VMX_EPT_IPAT_BIT; 
>   
>  
> if (kvm_read_cr0_bits(vcpu, X86_CR0_CD)) {
>  
> if (kvm_check_has_quirk(vcpu->kvm, 
> KVM_X86_QUIRK_CD_NW_CLEARED))   
> return MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT; 
>  
> else  
>  
> return (MTRR_TYPE_UNCACHABLE << 
> VMX_EPT_MT_EPTE_SHIFT) | 
> VMX_EPT_IPAT_BIT; 
>
> } 
>
>   
>
> return kvm_mtrr_get_guest_memory_type(vcpu, gfn) << 
> VMX_EPT_MT_EPTE_SHIFT;
> }
> 
> BTW, since the special memslot must be exposed to guest as virtio GPU BAR in
> order to prevent other guest drivers from access, I wonder if it's better to
> include some keyword like VIRTIO_GPU_BAR in memslot flag name.
Another choice is to add a memslot flag KVM_MEM_HONOR_GUEST_PAT, then user
(e.g. QEMU) does special treatment to this kind of memslots (e.g. skipping
reading/writing to them in general paths).

@@ -7589,26 +7589,29 @@ static u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t 
gfn, bool is_mmio)
if (is_mmio)
return MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT;

+   if (in_slot_honor_guest_pat(vcpu->kvm, gfn))
+   return 

Re: [PATCH v3 6/6] x86/vmware: Add TDX hypercall support

2023-12-19 Thread kirill . shutemov
On Tue, Dec 19, 2023 at 04:27:51PM -0800, Alexey Makhalov wrote:
> 
> 
> On 12/19/23 3:23 PM, kirill.shute...@linux.intel.com wrote:
> > On Tue, Dec 19, 2023 at 01:57:51PM -0800, Alexey Makhalov wrote:
> > > diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
> > > index 3aa1adaed18f..ef07ab7a07e1 100644
> > > --- a/arch/x86/kernel/cpu/vmware.c
> > > +++ b/arch/x86/kernel/cpu/vmware.c
> > > @@ -428,6 +428,30 @@ static bool __init 
> > > vmware_legacy_x2apic_available(void)
> > >   (eax & BIT(VCPU_LEGACY_X2APIC));
> > >   }
> > > +#ifdef CONFIG_INTEL_TDX_GUEST
> > > +unsigned long vmware_tdx_hypercall(unsigned long cmd,
> > > +struct tdx_module_args *args)
> > > +{
> > > + if (!hypervisor_is_type(X86_HYPER_VMWARE))
> > > + return 0;

BTW, don't you want to warn here to? We don't expect vmware hypercalls to
be called by non-vmware guest, do we?

> > > +
> > > + if (cmd & ~VMWARE_CMD_MASK) {
> > > + pr_warn("Out of range command %x\n", cmd);
> > > + return 0;
> > 
> > Is zero success? Shouldn't it be an error?
> 
> VMware hypercalls do not have a standard way of signalling an error.
> To generalize expectations from the caller perspective of any existing
> hypercalls: error (including hypercall is not supported or disabled) is when
> return value is 0 and out1/2 are unchanged or equal to in1/in2.

You are talking about signaling errors over hypercall transport. But if
kernel can see that something is wrong why cannot it signal the issue
clearly to caller. It is going to be in-kernel convention.

And to very least, it has to be pr_warn_once().

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


Re: [PATCH v3 2/6] x86/vmware: Introduce vmware_hypercall API

2023-12-19 Thread kirill . shutemov
On Tue, Dec 19, 2023 at 04:17:40PM -0800, Alexey Makhalov wrote:
> 
> 
> On 12/19/23 3:20 PM, kirill.shute...@linux.intel.com wrote:
> > On Tue, Dec 19, 2023 at 01:57:47PM -0800, Alexey Makhalov wrote:
> > > +static inline
> > > +unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
> > ...
> > > +static inline
> > > +unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
> > > + uint32_t *out1, uint32_t *out2)
> > ...
> > > +static inline
> > > +unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
> > > + uint32_t *out1, uint32_t *out2,
> > > + uint32_t *out3)
> > ...
> > > +static inline
> > > +unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
> > > + unsigned long in3, unsigned long in4,
> > > + unsigned long in5, uint32_t *out2)
> > ...
> > > +static inline
> > > +unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
> > > + unsigned long in3, uint32_t *out2,
> > > + uint32_t *out3, uint32_t *out4,
> > > + uint32_t *out5)
> > ...
> > > +static inline
> > > +unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
> > > + unsigned long in3, unsigned long in4,
> > > + unsigned long in5, uint32_t *out1,
> > > + uint32_t *out2, uint32_t *out3)
> > 
> > Naming is weird. The number in the name doesn't help much as there seems
> > no system on how many of the parameters are ins and outs.
> 
> There was internal discussion on hypercall API naming. One of proposals was
> using 2 digits - number of input and number of output arguments.
> And it definitely looked weird. So, we agreed to have just single number  -
> total number of arguments excluding cmd.

Have you considered naming them by number of input parameters? Number of
output parameters as demanded by users.

So vmware_hypercall4() will become vmware_hypercall1() and current
vmware_hypercall1() and vmware_hypercall3() will go away.

It is still awful, but /maybe/ better that this, I donno.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


Re: [PATCH v3 6/6] x86/vmware: Add TDX hypercall support

2023-12-19 Thread Alexey Makhalov




On 12/19/23 3:23 PM, kirill.shute...@linux.intel.com wrote:

On Tue, Dec 19, 2023 at 01:57:51PM -0800, Alexey Makhalov wrote:

diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 3aa1adaed18f..ef07ab7a07e1 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -428,6 +428,30 @@ static bool __init vmware_legacy_x2apic_available(void)
(eax & BIT(VCPU_LEGACY_X2APIC));
  }
  
+#ifdef CONFIG_INTEL_TDX_GUEST

+unsigned long vmware_tdx_hypercall(unsigned long cmd,
+  struct tdx_module_args *args)
+{
+   if (!hypervisor_is_type(X86_HYPER_VMWARE))
+   return 0;
+
+   if (cmd & ~VMWARE_CMD_MASK) {
+   pr_warn("Out of range command %x\n", cmd);
+   return 0;


Is zero success? Shouldn't it be an error?


VMware hypercalls do not have a standard way of signalling an error.
To generalize expectations from the caller perspective of any existing 
hypercalls: error (including hypercall is not supported or disabled) is 
when return value is 0 and out1/2 are unchanged or equal to in1/in2.


All existing vmware_hypercall callers will gracefully handle returned 0.
But they should never hit this path, as 0 bail out was introduced as a 
protection for the case where exported vmware_tdx_hypercall is used by 
random caller (not following VMware hypercall ABI).





+   }
+
+   args->r10 = VMWARE_TDX_VENDOR_LEAF;
+   args->r11 = VMWARE_TDX_HCALL_FUNC;
+   args->r12 = VMWARE_HYPERVISOR_MAGIC;
+   args->r13 = cmd;
+
+   __tdx_hypercall(args);
+
+   return args->r12;
+}
+EXPORT_SYMBOL_GPL(vmware_tdx_hypercall);
+#endif
+
  #ifdef CONFIG_AMD_MEM_ENCRYPT
  static void vmware_sev_es_hcall_prepare(struct ghcb *ghcb,
struct pt_regs *regs)
--
2.39.0







[PULL] drm-xe-next v2

2023-12-19 Thread Rodrigo Vivi
Hi Dave and Sima,

Here goes a v2 of our first pull request.

First PR: https://lore.kernel.org/all/zxzta75g5vhcr...@intel.com/

The lack of committer signature blocked Dave's tools on getting that.
I'm sorry for that.

As you know we were maintaining this branch with rebases through this past
year, so I did the last rebase to fix the tags but ended up not signing off
the patches. Fixing this now and hopefully we are getting in and this rebases
will stop.

Besides that, I also included two more commits in this PR:
- One fix that would break the builds without CONFIG_FAULT_INJECTION
- One commit that removes the FW loading for blobs that are not in
  linux-firmware.git yet.

Thanks,
Rodrigo.

The following changes since commit a60501d7c2d3e70b3545b9b96576628e369d8e85:

  Merge tag 'drm-misc-next-2023-12-07' of 
git://anongit.freedesktop.org/drm/drm-misc into drm-next (2023-12-08 16:27:00 
+1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/xe/kernel.git 
tags/drm-xe-next-2023-12-19-pr1

for you to fetch changes up to ba43af4e32ca80b2b977281d53636a75a93ca530:

  drm/xe: Remove ci-only GuC FW definitions (2023-12-19 18:52:21 -0500)


Introduce a new DRM driver for Intel GPUs

Xe, is a new driver for Intel GPUs that supports both integrated and
discrete platforms. The experimental support starts with Tiger Lake.
i915 will continue be the main production driver for the platforms
up to Meteor Lake and Alchemist. Then the goal is to make this Intel
Xe driver the primary driver for Lunar Lake and newer platforms.

It uses most, if not all, of the key drm concepts, in special: TTM,
drm-scheduler, drm-exec, drm-gpuvm/gpuva and others.


Alan Previn (1):
  drm/xe/guc: Fix h2g_write usage of GUC_CTB_MSG_MAX_LEN

Alexander Usyskin (1):
  drm/xe/gsc: enable pvc support

Andrzej Hajda (1):
  drm/xe: implement driver initiated function-reset

Animesh Manna (1):
  drm/xe/dsb: DSB implementation for xe

Anshuman Gupta (7):
  drm/xe/pm: Disable PM on unbounded pcie parent bridge
  drm/xe/pm: Add pci d3cold_capable support
  drm/xe/pm: Refactor xe_pm_runtime_init
  drm/xe/pm: Add vram_d3cold_threshold Sysfs
  drm/xe/pm: Toggle d3cold_allowed using vram_usages
  drm/xe/pm: Init pcode and restore vram on power lost
  drm/xe/pm: Add vram_d3cold_threshold for d3cold capable device

Anusha Srivatsa (10):
  drm/xe/huc: Support for loading unversiond HuC
  drm/xe: Load HuC on Alderlake S
  drm/xe: GuC and HuC loading support for RKL
  drm/xe: Add Rocketlake device info
  drm/xe/kunit: Handle fake device creation for all platform/subplatform 
cases
  drm/xe: Add missing ADL entries to xe_test_wa
  drm/xe/rplu: s/ADLP/ALDERLAKE_P
  drm/xe/rpls: Add RPLS Support
  drm/xe/rpls: Add Stepping info for RPLS
  drm/xe: Add missing ADL entries to xe_test_wa

Aravind Iddamsetty (5):
  drm/xe: Get GT clock to nanosecs
  drm/xe: Use spinlock in forcewake instead of mutex
  drm/xe/pmu: Enable PMU interface
  drm/xe/pmu: Drop interrupt pmu event
  drm/xe: Fix lockdep warning in xe_force_wake calls

Ashutosh Dixit (2):
  drm/xe/uapi: Use common drm_xe_ext_set_property extension
  drm/xe/pmu: Remove PMU from Xe till uapi is finalized

Badal Nilawar (11):
  drm/xe: Donot apply forcewake while reading actual frequency
  drm/xe/mtl: Add support to get C6 residency/status of MTL
  drm/xe/hwmon: Expose power attributes
  drm/xe/hwmon: Expose card reactive critical power
  drm/xe/hwmon: Expose input voltage attribute
  drm/xe/hwmon: Expose hwmon energy attribute
  drm/xe: Extend rpX values extraction for future platforms
  drm/xe/hwmon: Add kernel doc and refactor xe hwmon
  drm/xe/hwmon: Protect hwmon rw attributes with hwmon_lock
  drm/xe/hwmon: Expose power1_max_interval
  drm/xe/mtl: Use 16.67 Mhz freq scale factor to get rpX

Balasubramani Vivekanandan (9):
  drm/xe/gt: Enable interrupt while initializing root gt
  drm/xe: Use max wopcm size when validating the preset GuC wopcm size
  drm/xe: Stop accepting value in xe_migrate_clear
  drm/xe: Keep all resize bar related prints inside xe_resize_vram_bar
  drm/xe/xe2: Add MOCS table
  drm/xe/lnl: Hook up MOCS table
  drm/xe: Leverage ComputeCS read L3 caching
  drm/xe: Add event tracing for CTB
  drm/xe/trace: Optimize trace definition

Bommithi Sakeena (3):
  drm/xe: Ensure mutex are destroyed
  drm/xe: Add a missing mutex_destroy to xe_ttm_vram_mgr
  drm/xe: Encapsulate all the module parameters

Bommu Krishnaiah (2):
  drm/xe/uapi: add exec_queue_id member to drm_xe_wait_user_fence structure
  drm/xe/uapi: Return correct error code for xe_wait_user_fence_ioctl

Brian Welty (12):
  drm/xe: Fix BUG_ON during bind with prefetch
   

Re: [PATCH v3 2/6] x86/vmware: Introduce vmware_hypercall API

2023-12-19 Thread Alexey Makhalov




On 12/19/23 3:20 PM, kirill.shute...@linux.intel.com wrote:

On Tue, Dec 19, 2023 at 01:57:47PM -0800, Alexey Makhalov wrote:

+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)

...

+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2)

...

+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2,
+   uint32_t *out3)

...

+static inline
+unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
+   unsigned long in3, unsigned long in4,
+   unsigned long in5, uint32_t *out2)

...

+static inline
+unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
+   unsigned long in3, uint32_t *out2,
+   uint32_t *out3, uint32_t *out4,
+   uint32_t *out5)

...

+static inline
+unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
+   unsigned long in3, unsigned long in4,
+   unsigned long in5, uint32_t *out1,
+   uint32_t *out2, uint32_t *out3)


Naming is weird. The number in the name doesn't help much as there seems
no system on how many of the parameters are ins and outs.


There was internal discussion on hypercall API naming. One of proposals 
was using 2 digits - number of input and number of output arguments.
And it definitely looked weird. So, we agreed to have just single number 
 - total number of arguments excluding cmd.




Why these combinations of ins/outs are supported?


VMware hypercalls can use up to 6 ins and 6 outs for LB and 7 ins and 7 
outs for HB calls. The mapping to x86 registers is below:

in0/out0 - rax
in1/out1 - rbx
in2/out2 - rcx
in3/out3 - rdx
in4/out4 - rsi
in5/out5 - rdi
in6/out6 - rbp (only used in high bandwidth hypercalls)
args 0, 2 and 6 are remapped to r12, r13 and r14 for TDX.

There is a standard on some arguments such as cmd on in2, magic on in0 
and output value is on out0. While other arguments are not standardized 
across hypercall.


Theoreticaly max hypercall, in term of number of arguments:
vmware_hypercall9(cmd, in1, in3, in4, in5, *out1, *out2, *out3, *out4, 
*out5)

But there is no such called in a linux kernel.

Current combination of hypercalls covers all current and future (not yet 
upstreamed) callers, with round up to next number in some cases.





And as an outsider, I'm curious where in2 got lost :P


'lost' arguments:
in0 - indirectly initialized inside hypercall function.
out0 - return value from the hypercall.
[LB hypercalls] in2 <- input cmd
[HB hypercalls] in1 <- input cmd


Regards,
--Alexey



Re: [net-next v1 08/16] memory-provider: dmabuf devmem memory provider

2023-12-19 Thread Pavel Begunkov

On 12/14/23 20:03, Mina Almasry wrote:

On Mon, Dec 11, 2023 at 12:37 PM Pavel Begunkov  wrote:
...

If you remove the branch, let it fall into ->release and rely
on refcounting there, then the callback could also fix up
release_cnt or ask pp to do it, like in the patch I linked above



Sadly I don't think this is possible due to the reasons I mention in
the commit message of that patch. Prematurely releasing ppiov and not
having them be candidates for recycling shows me a 4-5x degradation in
performance.


I don't think I follow. The concept is to only recycle a buffer (i.e.
make it available for allocation) when its refs drop to zero, which is
IMHO the only way it can work, and IIUC what this patchset is doing.

That's also I suggest to do, but through a slightly different path.
Let's say at some moment there are 2 refs (e.g. 1 for an skb and
1 for userspace/xarray).

Say it first puts the skb:

napi_pp_put_page()
-> page_pool_return_page()
  -> mp_ops->release_page()
 -> need_to_free = put_buf()
// not last ref, need_to_free==false,
// don't recycle, don't increase release_cnt

Then you put the last ref:

page_pool_iov_put_many()
-> page_pool_return_page()
  -> mp_ops->release_page()
 -> need_to_free = put_buf()
// last ref, need_to_free==true,
// recycle and release_cnt++

And that last put can even be recycled right into the
pp / ptr_ring, in which case it doesn't need to touch
release_cnt. Does it make sense? I don't see where
4-5x degradation would come from




Sorry for the late reply, I have been working on this locally.

What you're saying makes sense, and I'm no longer sure why I was
seeing a perf degradation without '[net-next v1 10/16] page_pool:
don't release iov on elevanted refcount'. However, even though what
you're saying is technically correct, AFAIU it's actually semantically
wrong. When a page is released by the page_pool, we should call
page_pool_clear_pp_info() and completely disconnect the page from the
pool. If we call release_page() on a page and then the page pool sees
it again in page_pool_return_page(), I think that is considered a bug.


You're adding a new feature the semantics of which is already
different from what is in there, you can extend it any way as long
as it makes sense and agreed on. IMHO, it does. But well, if
there is a better solution I'm all for it.


In fact I think what you're proposing is as a result of a bug because
we don't call a page_pool_clear_pp_info() equivalent on releasing
ppiov.


I don't get it, what bug? page_pool_clear_pp_info() is not called
for ppiov because it doesn't make sense to call it for ppiov,
there is no reason to clear ppiov->pp, nor there is any pp_magic.



However, I'm reasonably confident I figured out the right thing to do
here. The page_pool uses page->pp_frag_count for its refcounting.
pp_frag_count is a misnomer, it's being renamed to pp_ref_count in
Liang's series[1]). In this series I used a get_page/put_page
equivalent for refcounting. Once I transitioned to using
pp_[frag|ref]_count for refcounting inside the page_pool, the issue
went away, and I no longer need the patch 'page_pool: don't release
iov on elevanted refcount'.


Lovely, I'll take a look later! (also assuming it's in v5)



There is an additional upside, since pages and ppiovs are both being
refcounted using pp_[frag|ref]_count, we get some unified handling for
ppiov and we reduce the checks around ppiov. This should be fixed
properly in the next series.

I still need to do some work (~1 week) before I upload the next
version as there is a new requirement from MM that we transition to a
new type and not re-use page*, but I uploaded my changes github with
the refcounting issues resolved in case they're useful to you. Sorry
for the churn:

https://github.com/mina/linux/commits/tcpdevmem-v1.5/

[1] https://patchwork.kernel.org/project/netdevbpf/list/?series=809049=*



--
Pavel Begunkov


Re: [PATCH v3 6/6] x86/vmware: Add TDX hypercall support

2023-12-19 Thread kirill . shutemov
On Tue, Dec 19, 2023 at 01:57:51PM -0800, Alexey Makhalov wrote:
> diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
> index 3aa1adaed18f..ef07ab7a07e1 100644
> --- a/arch/x86/kernel/cpu/vmware.c
> +++ b/arch/x86/kernel/cpu/vmware.c
> @@ -428,6 +428,30 @@ static bool __init vmware_legacy_x2apic_available(void)
>   (eax & BIT(VCPU_LEGACY_X2APIC));
>  }
>  
> +#ifdef CONFIG_INTEL_TDX_GUEST
> +unsigned long vmware_tdx_hypercall(unsigned long cmd,
> +struct tdx_module_args *args)
> +{
> + if (!hypervisor_is_type(X86_HYPER_VMWARE))
> + return 0;
> +
> + if (cmd & ~VMWARE_CMD_MASK) {
> + pr_warn("Out of range command %x\n", cmd);
> + return 0;

Is zero success? Shouldn't it be an error?

> + }
> +
> + args->r10 = VMWARE_TDX_VENDOR_LEAF;
> + args->r11 = VMWARE_TDX_HCALL_FUNC;
> + args->r12 = VMWARE_HYPERVISOR_MAGIC;
> + args->r13 = cmd;
> +
> + __tdx_hypercall(args);
> +
> + return args->r12;
> +}
> +EXPORT_SYMBOL_GPL(vmware_tdx_hypercall);
> +#endif
> +
>  #ifdef CONFIG_AMD_MEM_ENCRYPT
>  static void vmware_sev_es_hcall_prepare(struct ghcb *ghcb,
>   struct pt_regs *regs)
> -- 
> 2.39.0
> 

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


Re: [PATCH v3 2/6] x86/vmware: Introduce vmware_hypercall API

2023-12-19 Thread kirill . shutemov
On Tue, Dec 19, 2023 at 01:57:47PM -0800, Alexey Makhalov wrote:
> +static inline
> +unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
...
> +static inline
> +unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
> + uint32_t *out1, uint32_t *out2)
...
> +static inline
> +unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
> + uint32_t *out1, uint32_t *out2,
> + uint32_t *out3)
...
> +static inline
> +unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
> + unsigned long in3, unsigned long in4,
> + unsigned long in5, uint32_t *out2)
...
> +static inline
> +unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
> + unsigned long in3, uint32_t *out2,
> + uint32_t *out3, uint32_t *out4,
> + uint32_t *out5)
...
> +static inline
> +unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
> + unsigned long in3, unsigned long in4,
> + unsigned long in5, uint32_t *out1,
> + uint32_t *out2, uint32_t *out3)

Naming is weird. The number in the name doesn't help much as there seems
no system on how many of the parameters are ins and outs.

Why these combinations of ins/outs are supported?

And as an outsider, I'm curious where in2 got lost :P

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


Re: [PATCH v6] drm/msm/dpu: improve DSC allocation

2023-12-19 Thread Dmitry Baryshkov
On Tue, 19 Dec 2023 at 18:18, Kuogee Hsieh  wrote:
>
> Hi Dmitry,
>
> Anymore comments from you?

No, for some reason I missed this patch. Please excuse me.

> On 12/14/2023 10:56 AM, Kuogee Hsieh wrote:
> > At DSC V1.1 DCE (Display Compression Engine) contains a DSC encoder.
> > However, at DSC V1.2 DCE consists of two DSC encoders, one has an odd
> > index and another one has an even index. Each encoder can work
> > independently. But only two DSC encoders from same DCE can be paired
> > to work together to support DSC merge mode at DSC V1.2. For DSC V1.1
> > two consecutive DSC encoders (start with even index) have to be paired
> > to support DSC merge mode.  In addition, the DSC with even index have
> > to be mapped to even PINGPONG index and DSC with odd index have to be
> > mapped to odd PINGPONG index at its data path in regardless of DSC
> > V1.1 or V1.2. This patch improves DSC allocation mechanism with
> > consideration of those factors.
> >
> > Changes in V6:
> > -- rename _dpu_rm_reserve_dsc_single to _dpu_rm_dsc_alloc
> > -- rename _dpu_rm_reserve_dsc_pair to _dpu_rm_dsc_alloc_pair
> > -- pass global_state to _dpu_rm_pingpong_next_index()
> > -- remove pp_max
> > -- fix for loop condition check at _dpu_rm_dsc_alloc()
> >
> > Changes in V5:
> > -- delete dsc_id[]
> > -- update to global_state->dsc_to_enc_id[] directly
> > -- replace ndx with idx
> > -- fix indentation at function declaration
> > -- only one for loop at _dpu_rm_reserve_dsc_single()
> >
> > Changes in V4:
> > -- rework commit message
> > -- use reserved_by_other()
> > -- add _dpu_rm_pingpong_next_index()
> > -- revise _dpu_rm_pingpong_dsc_check()
> >
> > Changes in V3:
> > -- add dpu_rm_pingpong_dsc_check()
> > -- for pair allocation use i += 2 at for loop
> >
> > Changes in V2:
> >  -- split _dpu_rm_reserve_dsc() into _dpu_rm_reserve_dsc_single() and
> > _dpu_rm_reserve_dsc_pair()
> >
> > Fixes: f2803ee91a41 ("drm/msm/disp/dpu1: Add DSC support in RM")
> > Signed-off-by: Kuogee Hsieh 
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 154 
> > +
> >   1 file changed, 139 insertions(+), 15 deletions(-)

Reviewed-by: Dmitry Baryshkov 

See below for minor nit.

> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > index f9215643..0ce2a25 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > @@ -461,29 +461,153 @@ static int _dpu_rm_reserve_ctls(
> >   return 0;
> >   }
> >
> > -static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
> > -struct dpu_global_state *global_state,
> > -struct drm_encoder *enc,
> > -const struct msm_display_topology *top)
> > +static int _dpu_rm_pingpong_next_index(struct dpu_global_state 
> > *global_state,
> > +int start,

I'd still prefer to see `enum dpu_pingpong` as a parameter here
instead of just an index, but this is just my taste.

> > +uint32_t enc_id)
> >   {
> > - int num_dsc = top->num_dsc;
> >   int i;
> >
> > - /* check if DSC required are allocated or not */
> > - for (i = 0; i < num_dsc; i++) {
> > - if (!rm->dsc_blks[i]) {
> > - DPU_ERROR("DSC %d does not exist\n", i);
> > - return -EIO;
> > + for (i = start; i < (PINGPONG_MAX - PINGPONG_0); i++) {
> > + if (global_state->pingpong_to_enc_id[i] == enc_id)
> > + return i;
> > + }
> > +
> > + return -ENAVAIL;
> > +}
> > +
> > +static int _dpu_rm_pingpong_dsc_check(int dsc_idx, int pp_idx)
> > +{
> > + /*
> > +  * DSC with even index must be used with the PINGPONG with even index
> > +  * DSC with odd index must be used with the PINGPONG with odd index
> > +  */
> > + if ((dsc_idx & 0x01) != (pp_idx & 0x01))
> > + return -ENAVAIL;
> > +
> > + return 0;
> > +}
> > +
> > +static int _dpu_rm_dsc_alloc(struct dpu_rm *rm,
> > +  struct dpu_global_state *global_state,
> > +  uint32_t enc_id,
> > +  const struct msm_display_topology *top)
> > +{
> > + int num_dsc = 0;
> > + int pp_idx = 0;
> > + int dsc_idx;
> > + int ret;
> > +
> > + for (dsc_idx = 0; dsc_idx < ARRAY_SIZE(rm->dsc_blks) &&
> > +  num_dsc < top->num_dsc; dsc_idx++) {
> > + if (!rm->dsc_blks[dsc_idx])
> > + continue;
> > +
> > + if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, 
> > enc_id))
> > + continue;
> > +
> > + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, 
> > enc_id);
> > + if (pp_idx < 0)
> > + return -ENAVAIL;
> > +
> > + ret = _dpu_rm_pingpong_dsc_check(dsc_idx, pp_idx);
> > +  

Re: [PATCH 01/27] sparc32: Update defconfig to LEON SMP

2023-12-19 Thread Arnd Bergmann
On Tue, Dec 19, 2023, at 22:03, Sam Ravnborg via B4 Relay wrote:
> From: Sam Ravnborg 
>
> This is a copy of the leon_smp defconfig found in
> gaisler-buildroot-2023.02-1.0.
>
> Signed-off-by: Sam Ravnborg 
> Cc: "David S. Miller" 
> Cc: Arnd Bergmann 
> Cc: Andreas Larsson 

I did not get a cover letter for the series, but I looked at
all 27 patches and they all look good to me, nice cleanup!

Acked-by: Arnd Bergmann 


[PATCH 07/27] sparc32: Drop run-time patching of ipi trap

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

There is no longer any need for the run-time patching of the ipi trap
with the removal of sun4m and sun4d. Remove the patching and drop the
ipi implementation for the two machines.

The patch includes removal of patching from pcic as this was needed to
fix the build. pcic will be removed in a later commit.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/kernel/entry.S | 70 ++-
 arch/sparc/kernel/kernel.h|  4 ---
 arch/sparc/kernel/leon_smp.c  |  3 --
 arch/sparc/kernel/pcic.c  | 11 ---
 arch/sparc/kernel/sun4d_smp.c |  3 --
 arch/sparc/kernel/ttable_32.S |  9 +++---
 6 files changed, 7 insertions(+), 93 deletions(-)

diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index c6a5cb949381..7cf148a996b9 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -174,32 +174,6 @@ maybe_smp4m_msg_check_resched:
 maybe_smp4m_msg_out:
RESTORE_ALL
 
-   .align  4
-   .globl  linux_trap_ipi15_sun4m
-linux_trap_ipi15_sun4m:
-   SAVE_ALL
-   sethi   %hi(0x8000), %o2
-   GET_PROCESSOR4M_ID(o0)
-   sethi   %hi(sun4m_irq_percpu), %l5
-   or  %l5, %lo(sun4m_irq_percpu), %o5
-   sll %o0, 2, %o0
-   ld  [%o5 + %o0], %o5
-   ld  [%o5 + 0x00], %o3   ! sun4m_irq_percpu[cpu]->pending
-   andcc   %o3, %o2, %g0
-   be  sun4m_nmi_error ! Must be an NMI async memory error
-st %o2, [%o5 + 0x04]   ! 
sun4m_irq_percpu[cpu]->clear=0x8000
-   WRITE_PAUSE
-   ld  [%o5 + 0x00], %g0   ! sun4m_irq_percpu[cpu]->pending
-   WRITE_PAUSE
-   or  %l0, PSR_PIL, %l4
-   wr  %l4, 0x0, %psr
-   WRITE_PAUSE
-   wr  %l4, PSR_ET, %psr
-   WRITE_PAUSE
-   callsmp4m_cross_call_irq
-nop
-   b   ret_trap_lockless_ipi
-clr%l6
 
.globl  smp4d_ticker
/* SMP per-cpu ticker interrupts are handled specially. */
@@ -220,44 +194,6 @@ smp4d_ticker:
WRITE_PAUSE
RESTORE_ALL
 
-   .align  4
-   .globl  linux_trap_ipi15_sun4d
-linux_trap_ipi15_sun4d:
-   SAVE_ALL
-   sethi   %hi(CC_BASE), %o4
-   sethi   %hi(MXCC_ERR_ME|MXCC_ERR_PEW|MXCC_ERR_ASE|MXCC_ERR_PEE), %o2
-   or  %o4, (CC_EREG - CC_BASE), %o0
-   ldda[%o0] ASI_M_MXCC, %o0
-   andcc   %o0, %o2, %g0
-   bne 1f
-sethi  %hi(BB_STAT2), %o2
-   lduba   [%o2] ASI_M_CTL, %o2
-   andcc   %o2, BB_STAT2_MASK, %g0
-   bne 2f
-or %o4, (CC_ICLR - CC_BASE), %o0
-   sethi   %hi(1 << 15), %o1
-   stha%o1, [%o0] ASI_M_MXCC   /* Clear PIL 15 in MXCC's ICLR */
-   or  %l0, PSR_PIL, %l4
-   wr  %l4, 0x0, %psr
-   WRITE_PAUSE
-   wr  %l4, PSR_ET, %psr
-   WRITE_PAUSE
-   callsmp4d_cross_call_irq
-nop
-   b   ret_trap_lockless_ipi
-clr%l6
-
-1: /* MXCC error */
-2: /* BB error */
-   /* Disable PIL 15 */
-   set CC_IMSK, %l4
-   lduha   [%l4] ASI_M_MXCC, %l5
-   sethi   %hi(1 << 15), %l7
-   or  %l5, %l7, %l5
-   stha%l5, [%l4] ASI_M_MXCC
-   /* FIXME */
-1: b,a 1b
-
.globl  smpleon_ipi
.extern leon_ipi_interrupt
/* SMP per-cpu IPI interrupts are handled specially. */
@@ -618,11 +554,11 @@ sun4m_nmi_error:
 
 #ifndef CONFIG_SMP
.align  4
-   .globl  linux_trap_ipi15_sun4m
-linux_trap_ipi15_sun4m:
+   .globl  linux_trap_ipi15_leon
+linux_trap_ipi15_leon:
SAVE_ALL
 
-   ba  sun4m_nmi_error
+   ba  sun4m_nmi_error
 nop
 #endif /* CONFIG_SMP */
 
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index c8ba3bc7e137..1d3980ac0658 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -134,10 +134,6 @@ void leonsmp_ipi_interrupt(void);
 void leon_cross_call_irq(void);
 
 /* head_32.S */
-extern unsigned int t_nmi[];
-extern unsigned int linux_trap_ipi15_sun4d[];
-extern unsigned int linux_trap_ipi15_sun4m[];
-
 extern struct tt_entry trapbase;
 extern struct tt_entry trapbase_cpu1;
 extern struct tt_entry trapbase_cpu2;
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index 991e9ad3d3e8..42820c7422dd 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -463,8 +463,5 @@ static const struct sparc32_ipi_ops leon_ipi_ops = {
 
 void __init leon_init_smp(void)
 {
-   /* Patch ipi15 trap table */
-   t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m);
-
sparc32_ipi_ops = _ipi_ops;
 }
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 25fe0a061732..d952bcbbc395 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -354,17 +354,6 @@ int __init pcic_probe(void)
prom_getstring(node, "name", namebuf, 

[PATCH 12/27] sparc32: Drop mbus support

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Only used by older SPARC HW, not used by LEON.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/elf_32.h |  2 -
 arch/sparc/include/asm/mbus.h   | 97 -
 arch/sparc/kernel/cpu.c |  1 -
 arch/sparc/kernel/setup_32.c|  1 -
 arch/sparc/mm/iommu.c   | 18 ++--
 arch/sparc/mm/srmmu.c   | 48 
 6 files changed, 3 insertions(+), 164 deletions(-)

diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
index 37a6016c9ccd..b2cca9be55c2 100644
--- a/arch/sparc/include/asm/elf_32.h
+++ b/arch/sparc/include/asm/elf_32.h
@@ -91,8 +91,6 @@ typedef struct {
unsigned intpr_q[64];
 } elf_fpregset_t;
 
-#include 
-
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
diff --git a/arch/sparc/include/asm/mbus.h b/arch/sparc/include/asm/mbus.h
deleted file mode 100644
index 8b6dbe701b9b..
--- a/arch/sparc/include/asm/mbus.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * mbus.h:  Various defines for MBUS modules.
- *
- * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
- */
-
-#ifndef _SPARC_MBUS_H
-#define _SPARC_MBUS_H
-
-#include /* HyperSparc stuff */
-#include   /* Ugh, bug city... */
-
-enum mbus_module {
-   HyperSparc= 0,
-   Swift_ok  = 4,
-   Swift_bad_c   = 5,
-   Swift_lots_o_bugs = 6,
-   Tsunami   = 7,
-   Viking_12 = 8,
-   Viking_2x = 9,
-   Viking_30 = 10,
-   Viking_35 = 11,
-   Viking_new= 12,
-   TurboSparc= 13,
-   SRMMU_INVAL_MOD   = 14,
-};
-
-extern enum mbus_module srmmu_modtype;
-extern unsigned int viking_rev, swift_rev, cypress_rev;
-
-/* HW Mbus module bugs we have to deal with */
-#define HWBUG_COPYBACK_BROKEN0x0001
-#define HWBUG_ASIFLUSH_BROKEN0x0002
-#define HWBUG_VACFLUSH_BITROT0x0004
-#define HWBUG_KERN_ACCBROKEN 0x0008
-#define HWBUG_KERN_CBITBROKEN0x0010
-#define HWBUG_MODIFIED_BITROT0x0020
-#define HWBUG_PC_BADFAULT_ADDR   0x0040
-#define HWBUG_SUPERSCALAR_BAD0x0080
-#define HWBUG_PACINIT_BITROT 0x0100
-
-/* First the module type values. To find out which you have, just load
- * the mmu control register from ASI_M_MMUREG alternate address space and
- * shift the value right 28 bits.
- */
-/* IMPL field means the company which produced the chip. */
-#define MBUS_VIKING0x4   /* bleech, Texas Instruments Module */
-#define MBUS_LSI   0x3   /* LSI Logics */
-#define MBUS_ROSS  0x1   /* Ross is nice */
-#define MBUS_FMI   0x0   /* Fujitsu Microelectronics/Swift */
-
-/* Ross Module versions */
-#define ROSS_604_REV_CDE0x0   /* revisions c, d, and e */
-#define ROSS_604_REV_F  0x1   /* revision f */
-#define ROSS_6050xf   /* revision a, a.1, and a.2 */
-#define ROSS_605_REV_B  0xe   /* revision b */
-
-/* TI Viking Module versions */
-#define VIKING_REV_12   0x1   /* Version 1.2 or SPARCclassic's CPU */
-#define VIKING_REV_20x2   /* Version 2.1, 2.2, 2.3, and 2.4 */
-#define VIKING_REV_30   0x3   /* Version 3.0 */
-#define VIKING_REV_35   0x4   /* Version 3.5 */
-
-/* LSI Logics. */
-#define LSI_L64815 0x0
-
-/* Fujitsu */
-#define FMI_AURORA 0x4   /* MB8690x, a Swift module... */
-#define FMI_TURBO  0x5   /* MB86907, a TurboSparc module... */
-
-/* For multiprocessor support we need to be able to obtain the CPU id and
- * the MBUS Module id.
- */
-
-/* The CPU ID is encoded in the trap base register, 20 bits to the left of
- * bit zero, with 2 bits being significant.
- */
-#define TBR_ID_SHIFT20
-
-static inline int get_cpuid(void)
-{
-   register int retval;
-   __asm__ __volatile__("rd %%tbr, %0\n\t"
-"srl %0, %1, %0\n\t" :
-"=r" (retval) :
-"i" (TBR_ID_SHIFT));
-   return (retval & 3);
-}
-
-static inline int get_modid(void)
-{
-   return (get_cpuid() | 0x8);
-}
-
-   
-#endif /* !(_SPARC_MBUS_H) */
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 79cd6ccfeac0..cca7de051593 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -19,7 +19,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include "kernel.h"
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index e3b72a7b46d3..5a497140c52a 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -41,7 +41,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 

[PATCH 20/27] sparc32: Drop unused prom ranges support

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Drop support for prom ranges - not used anymore.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/oplib_32.h |  11 
 arch/sparc/prom/Makefile  |   1 -
 arch/sparc/prom/init_32.c |   2 -
 arch/sparc/prom/ranges.c  | 114 --
 4 files changed, 128 deletions(-)

diff --git a/arch/sparc/include/asm/oplib_32.h 
b/arch/sparc/include/asm/oplib_32.h
index d1cf3a27a40d..4ef7f05978d3 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -163,17 +163,6 @@ int prom_setprop(phandle node, const char *prop_name, char 
*prop_value,
 
 phandle prom_inst2pkg(int);
 
-/* Dorking with Bus ranges... */
-
-/* Apply promlib probes OBIO ranges to registers. */
-void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
-
-/* Apply ranges of any prom node (and optionally parent node as well) to 
registers. */
-void prom_apply_generic_ranges(phandle node, phandle parent,
-  struct linux_prom_registers *sbusregs, int 
nregs);
-
-void prom_ranges_init(void);
-
 /* CPU probing helpers.  */
 int cpu_find_by_instance(int instance, phandle *prom_node, int *mid);
 int cpu_find_by_mid(int mid, phandle *prom_node);
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile
index 397b79af77f7..6d94d8b28bcf 100644
--- a/arch/sparc/prom/Makefile
+++ b/arch/sparc/prom/Makefile
@@ -10,7 +10,6 @@ lib-y += init_$(BITS).o
 lib-$(CONFIG_SPARC32) += memory.o
 lib-y += misc_$(BITS).o
 lib-$(CONFIG_SPARC32) += mp.o
-lib-$(CONFIG_SPARC32) += ranges.o
 lib-y += console_$(BITS).o
 lib-y += printf.o
 lib-y += tree_$(BITS).o
diff --git a/arch/sparc/prom/init_32.c b/arch/sparc/prom/init_32.c
index d20470166cb1..1681f1f980d4 100644
--- a/arch/sparc/prom/init_32.c
+++ b/arch/sparc/prom/init_32.c
@@ -67,8 +67,6 @@ void __init prom_init(struct linux_romvec *rp)
 
prom_meminit();
 
-   prom_ranges_init();
-
printk("PROMLIB: Sun Boot Prom Version %d Revision %d\n",
   romvec->pv_romvers, prom_rev);
 
diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c
deleted file mode 100644
index 20cb828bc5f4..
--- a/arch/sparc/prom/ranges.c
+++ /dev/null
@@ -1,114 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * ranges.c: Handle ranges in newer proms for obio/sbus.
- *
- * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
- * Copyright (C) 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
- */
-
-#include 
-#include 
-
-#include 
-#include 
-#include 
-
-static struct linux_prom_ranges promlib_obio_ranges[PROMREG_MAX];
-static int num_obio_ranges;
-
-/* Adjust register values based upon the ranges parameters. */
-static void prom_adjust_regs(struct linux_prom_registers *regp, int nregs,
-struct linux_prom_ranges *rangep, int nranges)
-{
-   int regc, rngc;
-
-   for (regc = 0; regc < nregs; regc++) {
-   for (rngc = 0; rngc < nranges; rngc++)
-   if (regp[regc].which_io == rangep[rngc].ot_child_space)
-   break; /* Fount it */
-   if (rngc == nranges) /* oops */
-   prom_printf("adjust_regs: Could not find range with 
matching bus type...\n");
-   regp[regc].which_io = rangep[rngc].ot_parent_space;
-   regp[regc].phys_addr -= rangep[rngc].ot_child_base;
-   regp[regc].phys_addr += rangep[rngc].ot_parent_base;
-   }
-}
-
-static void prom_adjust_ranges(struct linux_prom_ranges *ranges1, int nranges1,
-  struct linux_prom_ranges *ranges2, int nranges2)
-{
-   int rng1c, rng2c;
-
-   for (rng1c = 0; rng1c < nranges1; rng1c++) {
-   for (rng2c = 0; rng2c < nranges2; rng2c++)
-   if (ranges1[rng1c].ot_parent_space == 
ranges2[rng2c].ot_child_space &&
-  ranges1[rng1c].ot_parent_base >= 
ranges2[rng2c].ot_child_base &&
-  ranges2[rng2c].ot_child_base + 
ranges2[rng2c].or_size - ranges1[rng1c].ot_parent_base > 0U)
-   break;
-   if (rng2c == nranges2) /* oops */
-   prom_printf("adjust_ranges: Could not find matching bus 
type...\n");
-   else if (ranges1[rng1c].ot_parent_base + ranges1[rng1c].or_size 
> ranges2[rng2c].ot_child_base + ranges2[rng2c].or_size)
-   ranges1[rng1c].or_size = ranges2[rng2c].ot_child_base + 
ranges2[rng2c].or_size - ranges1[rng1c].ot_parent_base;
-   ranges1[rng1c].ot_parent_space = ranges2[rng2c].ot_parent_space;
-   ranges1[rng1c].ot_parent_base += ranges2[rng2c].ot_parent_base;
-   }
-}
-
-/* Apply probed obio ranges to registers passed, if no ranges return. */
-void 

[PATCH 14/27] sparc32: Drop unused mmu models

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Drop mmu models not used by LEON, including their header files.
This includes removal of unused includes in various files to fix the
build.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/mxcc.h   | 138 ---
 arch/sparc/include/asm/ross.h   | 192 -
 arch/sparc/include/asm/swift.h  | 107 -
 arch/sparc/include/asm/tsunami.h|  65 ---
 arch/sparc/include/asm/turbosparc.h | 126 --
 arch/sparc/include/asm/viking.h | 255 
 arch/sparc/kernel/entry.S   |   1 -
 arch/sparc/mm/Makefile  |   1 -
 arch/sparc/mm/hypersparc.S  | 414 ---
 arch/sparc/mm/io-unit.c |   1 -
 arch/sparc/mm/iommu.c   |  31 +-
 arch/sparc/mm/mm_32.h   |   1 -
 arch/sparc/mm/srmmu.c   | 776 +---
 arch/sparc/mm/swift.S   | 256 
 arch/sparc/mm/tsunami.S | 132 --
 arch/sparc/mm/viking.S  | 284 -
 16 files changed, 21 insertions(+), 2759 deletions(-)

diff --git a/arch/sparc/include/asm/mxcc.h b/arch/sparc/include/asm/mxcc.h
deleted file mode 100644
index 3a2561bea4dd..
--- a/arch/sparc/include/asm/mxcc.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * mxcc.h:  Definitions of the Viking MXCC registers
- *
- * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
- */
-
-#ifndef _SPARC_MXCC_H
-#define _SPARC_MXCC_H
-
-/* These registers are accessed through ASI 0x2. */
-#define MXCC_DATSTREAM   0x1C0  /* Data stream register */
-#define MXCC_SRCSTREAM   0x1C00100  /* Source stream register */
-#define MXCC_DESSTREAM   0x1C00200  /* Destination stream register */
-#define MXCC_RMCOUNT 0x1C00300  /* Count of references and misses */
-#define MXCC_STEST   0x1C00804  /* Internal self-test */
-#define MXCC_CREG0x1C00A04  /* Control register */
-#define MXCC_SREG0x1C00B00  /* Status register */
-#define MXCC_RREG0x1C00C04  /* Reset register */
-#define MXCC_EREG0x1C00E00  /* Error code register */
-#define MXCC_PREG0x1C00F04  /* Address port register */
-
-/* Some MXCC constants. */
-#define MXCC_STREAM_SIZE 0x20   /* Size in bytes of one stream r/w */
-
-/* The MXCC Control Register:
- *
- * --
- * |   | RRC | RSV |PRE|MCE|PARE|ECE|RSV|
- * --
- *  31  1098-6   5   43   2  1-0
- *
- * RRC: Controls what you read from MXCC_RMCOUNT reg.
- *  0=Misses 1=References
- * PRE: Prefetch enable
- * MCE: Multiple Command Enable
- * PARE: Parity enable
- * ECE: External cache enable
- */
-
-#define MXCC_CTL_RRC   0x0200
-#define MXCC_CTL_PRE   0x0020
-#define MXCC_CTL_MCE   0x0010
-#define MXCC_CTL_PARE  0x0008
-#define MXCC_CTL_ECE   0x0004
-
-/* The MXCC Error Register:
- *
- * 
- * |ME| RSV|CE|PEW|PEE|ASE|EIV| MOPC|ECODE|PRIV|RSV|HPADDR|
- * 
- *  31   30 29  28  27  26  25 24-15  14-7   6  5-3   2-0
- *
- * ME: Multiple Errors have occurred
- * CE: Cache consistency Error
- * PEW: Parity Error during a Write operation
- * PEE: Parity Error involving the External cache
- * ASE: ASynchronous Error
- * EIV: This register is toast
- * MOPC: MXCC Operation Code for instance causing error
- * ECODE: The Error CODE
- * PRIV: A privileged mode error? 0=no 1=yes
- * HPADDR: High PhysicalADDRess bits (35-32)
- */
-
-#define MXCC_ERR_ME 0x8000
-#define MXCC_ERR_CE 0x2000
-#define MXCC_ERR_PEW0x1000
-#define MXCC_ERR_PEE0x0800
-#define MXCC_ERR_ASE0x0400
-#define MXCC_ERR_EIV0x0200
-#define MXCC_ERR_MOPC   0x01FF8000
-#define MXCC_ERR_ECODE  0x7F80
-#define MXCC_ERR_PRIV   0x0040
-#define MXCC_ERR_HPADDR 0x000f
-
-/* The MXCC Port register:
- *
- * -
- * || MID ||
- * -
- *  3121 20-18 17 0
- *
- * MID: The moduleID of the cpu your read this from.
- */
-
-#ifndef __ASSEMBLY__
-
-static inline void mxcc_set_stream_src(unsigned long *paddr)
-{
-   unsigned long data0 = paddr[0];
-   unsigned long data1 = paddr[1];
-
-   __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t"
- "or %%g0, %1, %%g3\n\t"
- "stda %%g2, [%2] %3\n\t" : :
- "r" (data0), "r" (data1),
- "r" (MXCC_SRCSTREAM),
- 

[PATCH 13/27] sparc32: Drop unused function __get_{phys,iospace}

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Not used and references stuff that will be dropped later.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/pgtable_32.h | 24 
 arch/sparc/include/asm/pgtsrmmu.h   | 11 ---
 2 files changed, 35 deletions(-)

diff --git a/arch/sparc/include/asm/pgtable_32.h 
b/arch/sparc/include/asm/pgtable_32.h
index 9e85d57ac3f2..92b063531d5c 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -368,30 +368,6 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
return __pte(pte_val(pte) & ~SRMMU_SWP_EXCLUSIVE);
 }
 
-static inline unsigned long
-__get_phys (unsigned long addr)
-{
-   switch (sparc_cpu_model){
-   case sun4m:
-   case sun4d:
-   return ((srmmu_get_pte (addr) & 0xff00) << 4);
-   default:
-   return 0;
-   }
-}
-
-static inline int
-__get_iospace (unsigned long addr)
-{
-   switch (sparc_cpu_model){
-   case sun4m:
-   case sun4d:
-   return (srmmu_get_pte (addr) >> 28);
-   default:
-   return -1;
-   }
-}
-
 /*
  * For sparc32&64, the pfn in io_remap_pfn_range() carries  in
  * its high 4 bits.  These macros/functions put it there or get it from there.
diff --git a/arch/sparc/include/asm/pgtsrmmu.h 
b/arch/sparc/include/asm/pgtsrmmu.h
index 18e68d43f036..7cb5cbc83211 100644
--- a/arch/sparc/include/asm/pgtsrmmu.h
+++ b/arch/sparc/include/asm/pgtsrmmu.h
@@ -125,17 +125,6 @@ static inline void srmmu_flush_whole_tlb(void)
 
 }
 
-static inline int
-srmmu_get_pte (unsigned long addr)
-{
-   register unsigned long entry;
-
-   __asm__ __volatile__("\n\tlda [%1] %2,%0\n\t" :
-   "=r" (entry):
-   "r" ((addr & 0xf000) | 0x400), "i" 
(ASI_M_FLUSH_PROBE));
-   return entry;
-}
-
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(_SPARC_PGTSRMMU_H) */

-- 
2.34.1



[PATCH 06/27] sparc32: Drop auxio support

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

auxio is not supported by LEON - so drop it.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/auxio_32.h |  73 +---
 arch/sparc/kernel/Makefile|   2 +-
 arch/sparc/kernel/auxio_32.c  | 139 --
 arch/sparc/kernel/devices.c   |   3 -
 arch/sparc/kernel/kernel.h|   4 --
 arch/sparc/kernel/process_32.c|  10 ---
 arch/sparc/prom/misc_32.c |   2 -
 7 files changed, 3 insertions(+), 230 deletions(-)

diff --git a/arch/sparc/include/asm/auxio_32.h 
b/arch/sparc/include/asm/auxio_32.h
index 852457c7a265..e2335ddd359d 100644
--- a/arch/sparc/include/asm/auxio_32.h
+++ b/arch/sparc/include/asm/auxio_32.h
@@ -1,43 +1,12 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * auxio.h:  Definitions and code for the Auxiliary I/O register.
+ * Dummy definitions for the Auxiliary I/O register.
  *
  * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
  */
 #ifndef _SPARC_AUXIO_H
 #define _SPARC_AUXIO_H
 
-#include 
-
-/* This register is an unsigned char in IO space.  It does two things.
- * First, it is used to control the front panel LED light on machines
- * that have it (good for testing entry points to trap handlers and irq's)
- * Secondly, it controls various floppy drive parameters.
- */
-#define AUXIO_ORMEIN  0xf0/* All writes must set these bits. */
-#define AUXIO_ORMEIN4M0xc0/* sun4m - All writes must set these bits. */
-#define AUXIO_FLPY_DENS   0x20/* Floppy density, high if set. Read only. */
-#define AUXIO_FLPY_DCHG   0x10/* A disk change occurred.  Read only. */
-#define AUXIO_EDGE_ON 0x10/* sun4m - On means Jumper block is in. */
-#define AUXIO_FLPY_DSEL   0x08/* Drive select/start-motor. Write only. */
-#define AUXIO_LINK_TEST   0x08/* sun4m - On means TPE Carrier detect. */
-
-/* Set the following to one, then zero, after doing a pseudo DMA transfer. */
-#define AUXIO_FLPY_TCNT   0x04/* Floppy terminal count. Write only. */
-
-/* Set the following to zero to eject the floppy. */
-#define AUXIO_FLPY_EJCT   0x02/* Eject floppy disk.  Write only. */
-#define AUXIO_LED 0x01/* On if set, off if unset. Read/Write */
-
-#ifndef __ASSEMBLY__
-
-/*
- * NOTE: these routines are implementation dependent--
- * understand the hardware you are querying!
- */
-void set_auxio(unsigned char bits_on, unsigned char bits_off);
-unsigned char get_auxio(void); /* .../asm/floppy.h */
-
 /*
  * The following routines are provided for driver-compatibility
  * with sparc64 (primarily sunlance.c)
@@ -46,44 +15,6 @@ unsigned char get_auxio(void); /* .../asm/floppy.h */
 #define AUXIO_LTE_ON1
 #define AUXIO_LTE_OFF   0
 
-/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
- *
- * on - AUXIO_LTE_ON or AUXIO_LTE_OFF
- */
-#define auxio_set_lte(on) \
-do { \
-   if(on) { \
-   set_auxio(AUXIO_LINK_TEST, 0); \
-   } else { \
-   set_auxio(0, AUXIO_LINK_TEST); \
-   } \
-} while (0)
-
-#define AUXIO_LED_ON1
-#define AUXIO_LED_OFF   0
-
-/* auxio_set_led - Set system front panel LED
- *
- * on - AUXIO_LED_ON or AUXIO_LED_OFF
- */
-#define auxio_set_led(on) \
-do { \
-   if(on) { \
-   set_auxio(AUXIO_LED, 0); \
-   } else { \
-   set_auxio(0, AUXIO_LED); \
-   } \
-} while (0)
-
-#endif /* !(__ASSEMBLY__) */
-
-
-/* AUXIO2 (Power Off Control) */
-extern volatile u8 __iomem *auxio_power_register;
-
-#defineAUXIO_POWER_DETECT_FAILURE  32
-#defineAUXIO_POWER_CLEAR_FAILURE   2
-#defineAUXIO_POWER_OFF 1
-
+#define auxio_set_lte(on)
 
 #endif /* !(_SPARC_AUXIO_H) */
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index ab47823f8b4e..577cb57c588a 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -83,7 +83,7 @@ obj-$(CONFIG_SMP) += trampoline_$(BITS).o 
smp_$(BITS).o
 obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o leon_smp.o
 obj-$(CONFIG_SPARC64_SMP) += hvtramp.o
 
-obj-y += auxio_$(BITS).o
+obj-$(CONFIG_SPARC64) += auxio_64.o
 
 obj-y += termios.o
 
diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c
deleted file mode 100644
index 989860e890c4..
--- a/arch/sparc/kernel/auxio_32.c
+++ /dev/null
@@ -1,139 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* auxio.c: Probing for the Sparc AUXIO register at boot time.
- *
- * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include /* memset(), Linux has no bzero() */
-#include 
-
-#include "kernel.h"
-
-/* Probe and map in the Auxiliary I/O register */
-
-/* auxio_register is not static because it is referenced 
- * in entry.S::floppy_tdone
- */
-void __iomem 

[PATCH 24/27] sparc32: Drop config SPARC_LEON

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

The only support sparc32 CPU is LEON, so there is no need for a
config option to select it.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/Kconfig   | 27 +--
 arch/sparc/configs/sparc32_defconfig |  1 -
 drivers/usb/host/Kconfig |  2 +-
 drivers/usb/host/ehci-hcd.c  |  4 ++--
 drivers/usb/host/uhci-hcd.c  |  2 +-
 5 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 7ae304bab2d8..0fc52c3c7487 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -9,6 +9,10 @@ config 64BIT
 
  Say yes to build a 64-bit kernel - formerly known as sparc64
  Say no to build a 32-bit kernel - formerly known as sparc
+ The 32-bit kernel target the synthesizable LEON SPARC processor.
+ LEON is a part of the GRLIB collection of IP cores that are
+ distributed under GPL. GRLIB can be downloaded from www.gaisler.com.
+ You can download a sparc-linux cross-compilation toolchain at 
www.gaisler.com.
 
 config SPARC
bool
@@ -60,6 +64,10 @@ config SPARC32
select HAVE_UID16
select LOCK_MM_AND_FIND_VMA
select OLD_SIGACTION
+   select USB_EHCI_BIG_ENDIAN_MMIO
+   select USB_EHCI_BIG_ENDIAN_DESC
+   select USB_UHCI_BIG_ENDIAN_MMIO
+   select USB_UHCI_BIG_ENDIAN_DESC
select ZONE_DMA
 
 config SPARC64
@@ -348,22 +356,6 @@ config SERIAL_CONSOLE
 
  If unsure, say N.
 
-config SPARC_LEON
-   bool "Sparc Leon processor family"
-   depends on SPARC32
-   select USB_EHCI_BIG_ENDIAN_MMIO
-   select USB_EHCI_BIG_ENDIAN_DESC
-   select USB_UHCI_BIG_ENDIAN_MMIO
-   select USB_UHCI_BIG_ENDIAN_DESC
-   help
- If you say Y here if you are running on a SPARC-LEON processor.
- The LEON processor is a synthesizable VHDL model of the
- SPARC-v8 standard. LEON is  part of the GRLIB collection of
- IP cores that are distributed under GPL. GRLIB can be downloaded
- from www.gaisler.com. You can download a sparc-linux cross-compilation
- toolchain at www.gaisler.com.
-
-if SPARC_LEON
 menu "U-Boot options"
 
 config UBOOT_LOAD_ADDR
@@ -394,7 +386,6 @@ config UBOOT_ENTRY_ADDR
 Kernel.
 
 endmenu
-endif
 
 endmenu
 
@@ -416,7 +407,7 @@ config SUN_LDOMS
 
 config LEON_PCI
bool
-   depends on PCI && SPARC_LEON
+   depends on PCI && SPARC32
default y
 
 config SPARC_GRPCI1
diff --git a/arch/sparc/configs/sparc32_defconfig 
b/arch/sparc/configs/sparc32_defconfig
index 71273fc578bf..dfd326f20876 100644
--- a/arch/sparc/configs/sparc32_defconfig
+++ b/arch/sparc/configs/sparc32_defconfig
@@ -10,7 +10,6 @@ CONFIG_BLK_DEV_INITRD=y
 # CONFIG_RD_ZSTD is not set
 CONFIG_SMP=y
 CONFIG_HZ_100=y
-CONFIG_SPARC_LEON=y
 CONFIG_SUN_OPENPROMFS=y
 CONFIG_SUN_OPENPROMIO=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 4448d0ab06f0..c5f94c70482f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -595,7 +595,7 @@ config USB_UHCI_HCD
 
 config USB_UHCI_SUPPORT_NON_PCI_HC
bool
-   default y if (SPARC_LEON || USB_UHCI_PLATFORM)
+   default y if (SPARC32 || USB_UHCI_PLATFORM)
 
 config USB_UHCI_PLATFORM
bool
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 802bfafb1012..5011bc8348bb 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1329,7 +1329,7 @@ MODULE_LICENSE ("GPL");
 #include "ehci-xilinx-of.c"
 #endif
 
-#ifdef CONFIG_SPARC_LEON
+#ifdef CONFIG_SPARC32
 #include "ehci-grlib.c"
 #endif
 
@@ -1343,7 +1343,7 @@ static struct platform_driver * const platform_drivers[] 
= {
 #ifdef CONFIG_XPS_USB_HCD_XILINX
_hcd_xilinx_of_driver,
 #endif
-#ifdef CONFIG_SPARC_LEON
+#ifdef CONFIG_SPARC32
_grlib_driver,
 #endif
 };
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index fd2408b553cf..7cb820963988 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -846,7 +846,7 @@ static const char hcd_name[] = "uhci_hcd";
 #definePCI_DRIVER  uhci_pci_driver
 #endif
 
-#ifdef CONFIG_SPARC_LEON
+#ifdef CONFIG_SPARC32
 #include "uhci-grlib.c"
 #define PLATFORM_DRIVERuhci_grlib_driver
 #endif

-- 
2.34.1



[PATCH 22/27] sparc32: Drop sun4m irq support

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Drop all code uses to support sun4m irqs.
Update entry.S to call the leon_nmi function.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/kernel/Makefile  |   1 -
 arch/sparc/kernel/entry.S   |  29 ++---
 arch/sparc/kernel/irq.h |  47 +---
 arch/sparc/kernel/irq_32.c  |   6 +-
 arch/sparc/kernel/kernel.h  |   4 -
 arch/sparc/kernel/leon_kernel.c |  10 +-
 arch/sparc/kernel/sun4m_irq.c   | 238 
 7 files changed, 23 insertions(+), 312 deletions(-)

diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 09577e39037c..1961d165b279 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -29,7 +29,6 @@ obj-y   += traps_$(BITS).o
 
 # IRQ
 obj-y   += irq_$(BITS).o
-obj-$(CONFIG_SPARC32)   += sun4m_irq.o
 
 obj-y   += process_$(BITS).o
 obj-y   += process.o
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index eecbe0be7bf6..fb6095aab9c2 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -427,36 +427,21 @@ setcc_trap_handler:
jmp %l2 ! advance over trap instruction
rett%l2 + 0x4   ! like this...
 
-sun4m_nmi_error:
+nmi_error:
/* NMI async memory error handling. */
-   sethi   %hi(0x8000), %l4
-   sethi   %hi(sun4m_irq_global), %o5
-   ld  [%o5 + %lo(sun4m_irq_global)], %l5
-   st  %l4, [%l5 + 0x0c]   ! sun4m_irq_global->mask_set=0x8000
-   WRITE_PAUSE
-   ld  [%l5 + 0x00], %g0   ! sun4m_irq_global->pending
-   WRITE_PAUSE
+#ifndef CONFIG_SMP
+   .align  4
+   .globl  linux_trap_ipi15_leon
+linux_trap_ipi15_leon:
+   SAVE_ALL
or  %l0, PSR_PIL, %l4
wr  %l4, 0x0, %psr
WRITE_PAUSE
wr  %l4, PSR_ET, %psr
WRITE_PAUSE
-   callsun4m_nmi
+   callleon_nmi
 nop
-   st  %l4, [%l5 + 0x08]   ! 
sun4m_irq_global->mask_clear=0x8000
-   WRITE_PAUSE
-   ld  [%l5 + 0x00], %g0   ! sun4m_irq_global->pending
-   WRITE_PAUSE
RESTORE_ALL
-
-#ifndef CONFIG_SMP
-   .align  4
-   .globl  linux_trap_ipi15_leon
-linux_trap_ipi15_leon:
-   SAVE_ALL
-
-   ba  sun4m_nmi_error
-nop
 #endif /* CONFIG_SMP */
 
.align  4
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h
index 8a0b314c8299..9d15dbb9fe6f 100644
--- a/arch/sparc/kernel/irq.h
+++ b/arch/sparc/kernel/irq.h
@@ -10,39 +10,14 @@ struct irq_bucket {
 unsigned int pil;
 };
 
-#define SUN4M_HARD_INT(x)   (0x1 << (x))
-#define SUN4M_SOFT_INT(x)   (0x1 << (x))
-
-#define SUN4D_MAX_BOARD 10
-#define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5)
+#define MAX_BOARD 10
+#define MAX_IRQ ((MAX_BOARD + 2) << 5)
 
 /* Map between the irq identifier used in hw to the
  * irq_bucket. The map is sufficient large to hold
  * the sun4d hw identifiers.
  */
-extern struct irq_bucket *irq_map[SUN4D_MAX_IRQ];
-
-
-/* sun4m specific type definitions */
-
-/* This maps direct to CPU specific interrupt registers */
-struct sun4m_irq_percpu {
-   u32 pending;
-   u32 clear;
-   u32 set;
-};
-
-/* This maps direct to global interrupt registers */
-struct sun4m_irq_global {
-   u32 pending;
-   u32 mask;
-   u32 mask_clear;
-   u32 mask_set;
-   u32 interrupt_target;
-};
-
-extern struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
-extern struct sun4m_irq_global __iomem *sun4m_irq_global;
+extern struct irq_bucket *irq_map[MAX_IRQ];
 
 unsigned int irq_alloc(unsigned int real_irq, unsigned int pil);
 void irq_link(unsigned int irq);
@@ -51,22 +26,8 @@ void handler_irq(unsigned int pil, struct pt_regs *regs);
 
 unsigned long leon_get_irqmask(unsigned int irq);
 
-/* sun4m_irq.c */
-void sun4m_nmi(struct pt_regs *regs);
-
-/* sun4d_irq.c */
-void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs);
-
 /* leon_kernel.c */
 void leon_clear_clock_irq(void);
 void leon_load_profile_irq(int cpu, unsigned int limit);
 u32 leon_cycles_offset(void);
-
-#ifdef CONFIG_SMP
-
-/* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
-#define SUN4D_IPI_IRQ 13
-
-void sun4d_ipi_interrupt(void);
-
-#endif
+void leon_nmi(struct pt_regs *regs);
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index f76f57073323..5bd64828e8a0 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -111,7 +111,7 @@ static struct irq_bucket irq_table[NR_IRQS];
 static DEFINE_SPINLOCK(irq_table_lock);
 
 /* Map between the irq identifier used in hw to the irq_bucket. */
-struct irq_bucket *irq_map[SUN4D_MAX_IRQ];
+struct irq_bucket *irq_map[MAX_IRQ];
 /* Protect access to irq_map */
 static DEFINE_SPINLOCK(irq_map_lock);
 

[PATCH 04/27] sparc32: Drop sun4m specific led driver

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

The led driver is only relevant for the sun4m machines.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/Kconfig |   9 ---
 arch/sparc/kernel/Makefile |   1 -
 arch/sparc/kernel/led.c| 146 -
 3 files changed, 156 deletions(-)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 54c91431724b..1520f68e944a 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -331,15 +331,6 @@ config SUN_PM
  Enable power management and CPU standby features on supported
  SPARC platforms.
 
-config SPARC_LED
-   tristate "Sun4m LED driver"
-   depends on SPARC32
-   help
- This driver toggles the front-panel LED on sun4m systems
- in a user-specifiable manner.  Its state can be probed
- by reading /proc/led and its blinking mode can be changed
- via writes to /proc/led
-
 config SERIAL_CONSOLE
bool
depends on SPARC32
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 0984bb6f0f17..95687af45d20 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -90,7 +90,6 @@ obj-y += termios.o
 
 obj-$(CONFIG_MODULES) += module.o
 obj-$(CONFIG_MODULES) += sparc_ksyms.o
-obj-$(CONFIG_SPARC_LED)   += led.o
 obj-$(CONFIG_KGDB)+= kgdb_$(BITS).o
 
 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c
deleted file mode 100644
index ab657b359789..
--- a/arch/sparc/kernel/led.c
+++ /dev/null
@@ -1,146 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-
-#define LED_MAX_LENGTH 8 /* maximum chars written to proc file */
-
-static inline void led_toggle(void)
-{
-   unsigned char val = get_auxio();
-   unsigned char on, off;
-
-   if (val & AUXIO_LED) {
-   on = 0;
-   off = AUXIO_LED;
-   } else {
-   on = AUXIO_LED;
-   off = 0;
-   }
-
-   set_auxio(on, off);
-}
-
-static struct timer_list led_blink_timer;
-static unsigned long led_blink_timer_timeout;
-
-static void led_blink(struct timer_list *unused)
-{
-   unsigned long timeout = led_blink_timer_timeout;
-
-   led_toggle();
-
-   /* reschedule */
-   if (!timeout) { /* blink according to load */
-   led_blink_timer.expires = jiffies +
-   ((1 + (avenrun[0] >> FSHIFT)) * HZ);
-   } else { /* blink at user specified interval */
-   led_blink_timer.expires = jiffies + (timeout * HZ);
-   }
-   add_timer(_blink_timer);
-}
-
-#ifdef CONFIG_PROC_FS
-static int led_proc_show(struct seq_file *m, void *v)
-{
-   if (get_auxio() & AUXIO_LED)
-   seq_puts(m, "on\n");
-   else
-   seq_puts(m, "off\n");
-   return 0;
-}
-
-static int led_proc_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, led_proc_show, NULL);
-}
-
-static ssize_t led_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
-   char *buf = NULL;
-
-   if (count > LED_MAX_LENGTH)
-   count = LED_MAX_LENGTH;
-
-   buf = memdup_user_nul(buffer, count);
-   if (IS_ERR(buf))
-   return PTR_ERR(buf);
-
-   /* work around \n when echo'ing into proc */
-   if (buf[count - 1] == '\n')
-   buf[count - 1] = '\0';
-
-   /* before we change anything we want to stop any running timers,
-* otherwise calls such as on will have no persistent effect
-*/
-   del_timer_sync(_blink_timer);
-
-   if (!strcmp(buf, "on")) {
-   auxio_set_led(AUXIO_LED_ON);
-   } else if (!strcmp(buf, "toggle")) {
-   led_toggle();
-   } else if ((*buf > '0') && (*buf <= '9')) {
-   led_blink_timer_timeout = simple_strtoul(buf, NULL, 10);
-   led_blink(_blink_timer);
-   } else if (!strcmp(buf, "load")) {
-   led_blink_timer_timeout = 0;
-   led_blink(_blink_timer);
-   } else {
-   auxio_set_led(AUXIO_LED_OFF);
-   }
-
-   kfree(buf);
-
-   return count;
-}
-
-static const struct proc_ops led_proc_ops = {
-   .proc_open  = led_proc_open,
-   .proc_read  = seq_read,
-   .proc_lseek = seq_lseek,
-   .proc_release   = single_release,
-   .proc_write = led_proc_write,
-};
-#endif
-
-#define LED_VERSION"0.1"
-
-static int __init led_init(void)
-{
-   timer_setup(_blink_timer, led_blink, 0);
-
-#ifdef CONFIG_PROC_FS
-   if (!proc_create("led", 0, NULL, _proc_ops))
-   return -ENOMEM;
-#endif
-   printk(KERN_INFO
-  "led: version %s, Lars Kotthoff 

[PATCH 03/27] sparc32: Drop floppy support

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

LEON do not have floppy support so we can drop it

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/Kconfig |   2 +-
 arch/sparc/include/asm/floppy.h|   2 -
 arch/sparc/include/asm/floppy_32.h | 393 -
 arch/sparc/kernel/entry.S  | 137 -
 arch/sparc/kernel/irq.h|   3 -
 arch/sparc/kernel/irq_32.c |  93 -
 arch/sparc/kernel/kernel.h |   2 -
 7 files changed, 1 insertion(+), 631 deletions(-)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 49849790e66d..54c91431724b 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -195,7 +195,7 @@ config GENERIC_CALIBRATE_DELAY
 
 config ARCH_MAY_HAVE_PC_FDC
bool
-   default y
+   default y if SPARC64
 
 config EMULATED_CMPXCHG
bool
diff --git a/arch/sparc/include/asm/floppy.h b/arch/sparc/include/asm/floppy.h
index 4b315802e635..c89f719a18e9 100644
--- a/arch/sparc/include/asm/floppy.h
+++ b/arch/sparc/include/asm/floppy.h
@@ -3,7 +3,5 @@
 #define ___ASM_SPARC_FLOPPY_H
 #if defined(__sparc__) && defined(__arch64__)
 #include 
-#else
-#include 
 #endif
 #endif
diff --git a/arch/sparc/include/asm/floppy_32.h 
b/arch/sparc/include/asm/floppy_32.h
deleted file mode 100644
index 836f6575aa1d..
--- a/arch/sparc/include/asm/floppy_32.h
+++ /dev/null
@@ -1,393 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* asm/floppy.h: Sparc specific parts of the Floppy driver.
- *
- * Copyright (C) 1995 David S. Miller (da...@davemloft.net)
- */
-
-#ifndef __ASM_SPARC_FLOPPY_H
-#define __ASM_SPARC_FLOPPY_H
-
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-/* We don't need no stinkin' I/O port allocation crap. */
-#undef release_region
-#undef request_region
-#define release_region(X, Y)   do { } while(0)
-#define request_region(X, Y, Z)(1)
-
-/* References:
- * 1) Netbsd Sun floppy driver.
- * 2) NCR 82077 controller manual
- * 3) Intel 82077 controller manual
- */
-struct sun_flpy_controller {
-   volatile unsigned char status_82072;  /* Main Status reg. */
-#define dcr_82072  status_82072   /* Digital Control reg. */
-#define status1_82077  status_82072   /* Auxiliary Status reg. 1 */
-
-   volatile unsigned char data_82072;/* Data fifo. */
-#define status2_82077  data_82072 /* Auxiliary Status reg. 2 */
-
-   volatile unsigned char dor_82077; /* Digital Output reg. */
-   volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
-
-   volatile unsigned char status_82077;  /* Main Status Register. */
-#define drs_82077  status_82077   /* Digital Rate Select reg. */
-
-   volatile unsigned char data_82077;/* Data fifo. */
-   volatile unsigned char ___unused;
-   volatile unsigned char dir_82077; /* Digital Input reg. */
-#define dcr_82077  dir_82077  /* Config Control reg. */
-};
-
-/* You'll only ever find one controller on a SparcStation anyways. */
-static struct sun_flpy_controller *sun_fdc = NULL;
-
-struct sun_floppy_ops {
-   unsigned char (*fd_inb)(int port);
-   void (*fd_outb)(unsigned char value, int port);
-};
-
-static struct sun_floppy_ops sun_fdops;
-
-#define fd_inb(base, reg) sun_fdops.fd_inb(reg)
-#define fd_outb(value, base, reg) sun_fdops.fd_outb(value, reg)
-#define fd_enable_dma()   sun_fd_enable_dma()
-#define fd_disable_dma()  sun_fd_disable_dma()
-#define fd_request_dma()  (0) /* nothing... */
-#define fd_free_dma() /* nothing... */
-#define fd_clear_dma_ff() /* nothing... */
-#define fd_set_dma_mode(mode) sun_fd_set_dma_mode(mode)
-#define fd_set_dma_addr(addr) sun_fd_set_dma_addr(addr)
-#define fd_set_dma_count(count)   sun_fd_set_dma_count(count)
-#define fd_enable_irq()   /* nothing... */
-#define fd_disable_irq()  /* nothing... */
-#define fd_request_irq()  sun_fd_request_irq()
-#define fd_free_irq() /* nothing... */
-#if 0  /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
-#define fd_dma_mem_alloc(size)((unsigned long) vmalloc(size))
-#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
-#endif
-
-/* XXX This isn't really correct. XXX */
-#define get_dma_residue(x)(0)
-
-#define FLOPPY0_TYPE  4
-#define FLOPPY1_TYPE  0
-
-/* Super paranoid... */
-#undef HAVE_DISABLE_HLT
-
-/* Here is where we catch the floppy driver trying to initialize,
- * therefore this is where we call the PROM device tree probing
- * routine etc. on the Sparc.
- */
-#define FDC1  sun_floppy_init()
-
-#define N_FDC1
-#define N_DRIVE  8
-
-/* No 64k boundary crossing problems on the Sparc. */
-#define CROSS_64KB(a,s) (0)
-
-/* Routines unique to each controller type on a Sun. */
-static void 

[PATCH 01/27] sparc32: Update defconfig to LEON SMP

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

This is a copy of the leon_smp defconfig found in
gaisler-buildroot-2023.02-1.0.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/configs/sparc32_defconfig | 171 +++
 1 file changed, 91 insertions(+), 80 deletions(-)

diff --git a/arch/sparc/configs/sparc32_defconfig 
b/arch/sparc/configs/sparc32_defconfig
index 5010164de3e4..71273fc578bf 100644
--- a/arch/sparc/configs/sparc32_defconfig
+++ b/arch/sparc/configs/sparc32_defconfig
@@ -1,97 +1,108 @@
+CONFIG_DEFAULT_HOSTNAME="leon"
 CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_PCI=y
-CONFIG_SUN_OPENPROMFS=m
-CONFIG_BINFMT_MISC=m
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+# CONFIG_RD_ZSTD is not set
+CONFIG_SMP=y
+CONFIG_HZ_100=y
+CONFIG_SPARC_LEON=y
+CONFIG_SUN_OPENPROMFS=y
+CONFIG_SUN_OPENPROMIO=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_COMPACTION is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
 CONFIG_INET=y
 CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_INET_AH=y
-CONFIG_INET_ESP=y
-CONFIG_INET_IPCOMP=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NET_PKTGEN=m
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_QLOGICPTI=m
-CONFIG_SCSI_SUNESP=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
-CONFIG_SUNLANCE=y
-CONFIG_HAPPYMEAL=m
-CONFIG_SUNBMAC=m
-CONFIG_SUNQE=m
+CONFIG_GRETH=y
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_GOOGLE is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+CONFIG_BROADCOM_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_STE10XP=y
+CONFIG_VITESSE_PHY=y
 # CONFIG_WLAN is not set
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-CONFIG_KEYBOARD_ATKBD=m
-CONFIG_KEYBOARD_SUNKBD=m
-CONFIG_MOUSE_PS2=m
-CONFIG_MOUSE_SERIAL=m
-CONFIG_SERIO=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO_I8042 is not set
 CONFIG_SERIAL_SUNZILOG=y
 CONFIG_SERIAL_SUNZILOG_CONSOLE=y
-CONFIG_SERIAL_SUNSU=y
-CONFIG_SERIAL_SUNSU_CONSOLE=y
-CONFIG_SPI=y
-CONFIG_SPI_XILINX=m
-CONFIG_SPI_XILINX_PLTFM=m
-CONFIG_SUN_OPENPROMIO=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_ISO9660_FS=m
+CONFIG_SERIAL_GRLIB_GAISLER_APBUART=y
+CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_HID_GENERIC is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_INTF_SYSFS is not set
+# CONFIG_RTC_INTF_PROC is not set
+# CONFIG_RTC_INTF_DEV is not set
+# CONFIG_VIRTIO_MENU is not set
+# CONFIG_VHOST_MENU is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_FSCACHE=y
 CONFIG_PROC_KCORE=y
-CONFIG_ROMFS_FS=m
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
-CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_NFS_FSCACHE=y
 CONFIG_NLS=y

[PATCH 11/27] sparc32: Drop pcic support

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

pcic is only used by MicroSPARC-IIep and not relevant for LEON.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/Kconfig|   5 -
 arch/sparc/include/asm/pcic.h | 130 ---
 arch/sparc/kernel/Makefile|   1 -
 arch/sparc/kernel/entry.S |  48 ---
 arch/sparc/kernel/irq_32.c|   1 -
 arch/sparc/kernel/kernel.h|   4 -
 arch/sparc/kernel/pcic.c  | 829 --
 arch/sparc/kernel/time_32.c   |   6 +-
 8 files changed, 1 insertion(+), 1023 deletions(-)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 55a9e67c482e..7ae304bab2d8 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -414,11 +414,6 @@ config SUN_LDOMS
  Say Y here is you want to support virtual devices via
  Logical Domains.
 
-config PCIC_PCI
-   bool
-   depends on PCI && SPARC32 && !SPARC_LEON
-   default y
-
 config LEON_PCI
bool
depends on PCI && SPARC_LEON
diff --git a/arch/sparc/include/asm/pcic.h b/arch/sparc/include/asm/pcic.h
deleted file mode 100644
index 238376b1ffcc..
--- a/arch/sparc/include/asm/pcic.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * pcic.h: JavaEngine 1 specific PCI definitions.
- *
- * Copyright (C) 1998 V. Roganov and G. Raiko
- */
-
-#ifndef __SPARC_PCIC_H
-#define __SPARC_PCIC_H
-
-#ifndef __ASSEMBLY__
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-struct linux_pcic {
-void __iomem*pcic_regs;
-unsigned long   pcic_io;
-void __iomem*pcic_config_space_addr;
-void __iomem*pcic_config_space_data;
-   struct resource pcic_res_regs;
-   struct resource pcic_res_io;
-   struct resource pcic_res_cfg_addr;
-   struct resource pcic_res_cfg_data;
-struct linux_pbm_info   pbm;
-   struct pcic_ca2irq  *pcic_imap;
-   int pcic_imdim;
-};
-
-#ifdef CONFIG_PCIC_PCI
-int pcic_present(void);
-int pcic_probe(void);
-void pci_time_init(void);
-void sun4m_pci_init_IRQ(void);
-#else
-static inline int pcic_present(void) { return 0; }
-static inline int pcic_probe(void) { return 0; }
-static inline void pci_time_init(void) {}
-static inline void sun4m_pci_init_IRQ(void) {}
-#endif
-#endif
-
-/* Size of PCI I/O space which we relocate. */
-#define PCI_SPACE_SIZE  0x100   /* 16 MB */
-
-/* PCIC Register Set. */
-#define PCI_DIAGNOSTIC_00x40/* 32 bits */
-#define PCI_SIZE_0  0x44/* 32 bits */
-#define PCI_SIZE_1  0x48/* 32 bits */
-#define PCI_SIZE_2  0x4c/* 32 bits */
-#define PCI_SIZE_3  0x50/* 32 bits */
-#define PCI_SIZE_4  0x54/* 32 bits */
-#define PCI_SIZE_5  0x58/* 32 bits */
-#define PCI_PIO_CONTROL 0x60/* 8  bits */
-#define PCI_DVMA_CONTROL0x62/* 8  bits */
-#define  PCI_DVMA_CONTROL_INACTIVITY_REQ(1<<0)
-#define  PCI_DVMA_CONTROL_IOTLB_ENABLE  (1<<0)
-#define  PCI_DVMA_CONTROL_IOTLB_DISABLE 0
-#define  PCI_DVMA_CONTROL_INACTIVITY_ACK(1<<4)
-#define PCI_INTERRUPT_CONTROL   0x63/* 8  bits */
-#define PCI_CPU_INTERRUPT_PENDING   0x64/* 32 bits */
-#define PCI_DIAGNOSTIC_10x68/* 16 bits */
-#define PCI_SOFTWARE_INT_CLEAR  0x6a/* 16 bits */
-#define PCI_SOFTWARE_INT_SET0x6e/* 16 bits */
-#define PCI_SYS_INT_PENDING 0x70/* 32 bits */
-#define  PCI_SYS_INT_PENDING_PIO   0x4000
-#define  PCI_SYS_INT_PENDING_DMA   0x2000
-#define  PCI_SYS_INT_PENDING_PCI   0x1000
-#define  PCI_SYS_INT_PENDING_APSR  0x0800
-#define PCI_SYS_INT_TARGET_MASK 0x74/* 32 bits */
-#define PCI_SYS_INT_TARGET_MASK_CLEAR   0x78/* 32 bits */
-#define PCI_SYS_INT_TARGET_MASK_SET 0x7c/* 32 bits */
-#define PCI_SYS_INT_PENDING_CLEAR   0x83/* 8  bits */
-#define  PCI_SYS_INT_PENDING_CLEAR_ALL 0x80
-#define  PCI_SYS_INT_PENDING_CLEAR_PIO 0x40
-#define  PCI_SYS_INT_PENDING_CLEAR_DMA 0x20
-#define  PCI_SYS_INT_PENDING_CLEAR_PCI 0x10
-#define PCI_IOTLB_CONTROL   0x84/* 8  bits */
-#define PCI_INT_SELECT_LO   0x88/* 16 bits */
-#define PCI_ARBITRATION_SELECT  0x8a/* 16 bits */
-#define PCI_INT_SELECT_HI   0x8c/* 16 bits */
-#define PCI_HW_INT_OUTPUT   0x8e/* 16 bits */
-#define PCI_IOTLB_RAM_INPUT 0x90/* 32 bits */
-#define PCI_IOTLB_CAM_INPUT 0x94/* 32 bits */
-#define PCI_IOTLB_RAM_OUTPUT0x98/* 32 bits */
-#define PCI_IOTLB_CAM_OUTPUT0x9c/* 32 bits */

[PATCH 09/27] sparc32: Drop sun4m/sun4d specific irq handling

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Some of the sun4m irq infrastructure is used by LEON too,
so keep that and drop the rest.
The patch include a few extra fixes fix the build after
the removal of the irq support.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/irq_32.h |   2 -
 arch/sparc/kernel/Makefile  |   2 +-
 arch/sparc/kernel/irq_32.c  |  30 +--
 arch/sparc/kernel/kernel.h  |  13 --
 arch/sparc/kernel/sun4d_irq.c   | 494 
 arch/sparc/kernel/sun4d_smp.c   |   4 -
 arch/sparc/kernel/sun4m_irq.c   | 240 ---
 arch/sparc/mm/io-unit.c |   2 -
 8 files changed, 2 insertions(+), 785 deletions(-)

diff --git a/arch/sparc/include/asm/irq_32.h b/arch/sparc/include/asm/irq_32.h
index 6ee48321cbc2..c402c81b85a7 100644
--- a/arch/sparc/include/asm/irq_32.h
+++ b/arch/sparc/include/asm/irq_32.h
@@ -17,8 +17,6 @@
 
 #define irq_canonicalize(irq)  (irq)
 
-void __init sun4d_init_sbi_irq(void);
-
 #define NO_IRQ 0x
 
 #endif
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 577cb57c588a..e79ef2049ea2 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -29,7 +29,7 @@ obj-y   += traps_$(BITS).o
 
 # IRQ
 obj-y   += irq_$(BITS).o
-obj-$(CONFIG_SPARC32)   += sun4m_irq.o sun4d_irq.o
+obj-$(CONFIG_SPARC32)   += sun4m_irq.o
 
 obj-y   += process_$(BITS).o
 obj-y   += process.o
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index 510184c3aa17..135170f362c1 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -235,36 +235,8 @@ void handler_irq(unsigned int pil, struct pt_regs *regs)
set_irq_regs(old_regs);
 }
 
-/* djhr
- * This could probably be made indirect too and assigned in the CPU
- * bits of the code. That would be much nicer I think and would also
- * fit in with the idea of being able to tune your kernel for your machine
- * by removing unrequired machine and device support.
- *
- */
-
 void __init init_IRQ(void)
 {
-   switch (sparc_cpu_model) {
-   case sun4m:
-   pcic_probe();
-   if (pcic_present())
-   sun4m_pci_init_IRQ();
-   else
-   sun4m_init_IRQ();
-   break;
-
-   case sun4d:
-   sun4d_init_IRQ();
-   break;
-
-   case sparc_leon:
-   leon_init_IRQ();
-   break;
-
-   default:
-   prom_printf("Cannot initialize IRQs on this Sun machine...");
-   break;
-   }
+   leon_init_IRQ();
 }
 
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 85a3c3d1195e..f090d34a2f56 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -93,7 +93,6 @@ extern spinlock_t irq_action_lock;
 void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs);
 
 /* sun4m_irq.c */
-void sun4m_init_IRQ(void);
 void sun4m_unmask_profile_irq(void);
 void sun4m_clear_profile_irq(int cpu);
 
@@ -106,18 +105,6 @@ void __init smp4m_smp_done(void);
 void smp4m_cross_call_irq(void);
 void smp4m_percpu_timer_interrupt(struct pt_regs *regs);
 
-/* sun4d_irq.c */
-extern spinlock_t sun4d_imsk_lock;
-
-void sun4d_init_IRQ(void);
-int sun4d_request_irq(unsigned int irq,
-  irq_handler_t handler,
-  unsigned long irqflags,
-  const char *devname, void *dev_id);
-int show_sun4d_interrupts(struct seq_file *, void *);
-void sun4d_distribute_irqs(void);
-void sun4d_free_irq(unsigned int irq, void *dev_id);
-
 /* sun4d_smp.c */
 void sun4d_cpu_pre_starting(void *arg);
 void sun4d_cpu_pre_online(void *arg);
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
deleted file mode 100644
index 7140cff04b54..
--- a/arch/sparc/kernel/sun4d_irq.c
+++ /dev/null
@@ -1,494 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * SS1000/SC2000 interrupt handling.
- *
- *  Copyright (C) 1997,1998 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
- *  Heavily based on arch/sparc/kernel/irq.c.
- */
-
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "kernel.h"
-#include "irq.h"
-
-/* Sun4d interrupts fall roughly into two categories.  SBUS and
- * cpu local.  CPU local interrupts cover the timer interrupts
- * and whatnot, and we encode those as normal PILs between
- * 0 and 15.
- * SBUS interrupts are encodes as a combination of board, level and slot.
- */
-
-struct sun4d_handler_data {
-   unsigned int cpuid;/* target cpu */
-   unsigned int real_irq; /* interrupt level */
-};
-
-
-static unsigned int sun4d_encode_irq(int board, int lvl, int slot)
-{
-   return (board + 1) << 5 | (lvl << 2) | slot;
-}
-
-struct sun4d_timer_regs {
-   u32 

[PATCH 10/27] sparc32: Drop sun4d/sun4m smp support

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Drop the sun4m and sun4d smp support code.

The sparc32 kernel will not boot unless this is a LEON system,
so drop checks for other systems as they will not trigger.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/kernel/Makefile|   2 +-
 arch/sparc/kernel/kernel.h|  18 --
 arch/sparc/kernel/smp_32.c| 102 +--
 arch/sparc/kernel/sun4d_smp.c | 408 --
 arch/sparc/kernel/sun4m_smp.c | 275 
 arch/sparc/mm/srmmu.c |  10 +-
 6 files changed, 8 insertions(+), 807 deletions(-)

diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index e79ef2049ea2..386bbb30fff2 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -80,7 +80,7 @@ obj-$(CONFIG_SPARC_GRPCI2)+= leon_pci_grpci2.o
 obj-$(CONFIG_SPARC_GRPCI1)+= leon_pci_grpci1.o
 
 obj-$(CONFIG_SMP) += trampoline_$(BITS).o smp_$(BITS).o
-obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o leon_smp.o
+obj-$(CONFIG_SPARC32_SMP) += leon_smp.o
 obj-$(CONFIG_SPARC64_SMP) += hvtramp.o
 
 obj-$(CONFIG_SPARC64) += auxio_64.o
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index f090d34a2f56..ff8f412e3153 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -96,24 +96,6 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * 
regs);
 void sun4m_unmask_profile_irq(void);
 void sun4m_clear_profile_irq(int cpu);
 
-/* sun4m_smp.c */
-void sun4m_cpu_pre_starting(void *arg);
-void sun4m_cpu_pre_online(void *arg);
-void __init smp4m_boot_cpus(void);
-int smp4m_boot_one_cpu(int i, struct task_struct *idle);
-void __init smp4m_smp_done(void);
-void smp4m_cross_call_irq(void);
-void smp4m_percpu_timer_interrupt(struct pt_regs *regs);
-
-/* sun4d_smp.c */
-void sun4d_cpu_pre_starting(void *arg);
-void sun4d_cpu_pre_online(void *arg);
-void __init smp4d_boot_cpus(void);
-int smp4d_boot_one_cpu(int i, struct task_struct *idle);
-void __init smp4d_smp_done(void);
-void smp4d_cross_call_irq(void);
-void smp4d_percpu_timer_interrupt(struct pt_regs *regs);
-
 /* leon_smp.c */
 void leon_cpu_pre_starting(void *arg);
 void leon_cpu_pre_online(void *arg);
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 87eaa7719fa2..42fb90577a82 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -87,29 +87,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
num, bogosum/(50/HZ),
(bogosum/(5000/HZ))%100);
 
-   switch(sparc_cpu_model) {
-   case sun4m:
-   smp4m_smp_done();
-   break;
-   case sun4d:
-   smp4d_smp_done();
-   break;
-   case sparc_leon:
-   leon_smp_done();
-   break;
-   case sun4e:
-   printk("SUN4E\n");
-   BUG();
-   break;
-   case sun4u:
-   printk("SUN4U\n");
-   BUG();
-   break;
-   default:
-   printk("UNKNOWN!\n");
-   BUG();
-   break;
-   }
+   leon_smp_done();
 }
 
 void cpu_panic(void)
@@ -191,29 +169,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 
smp_store_cpu_info(boot_cpu_id);
 
-   switch(sparc_cpu_model) {
-   case sun4m:
-   smp4m_boot_cpus();
-   break;
-   case sun4d:
-   smp4d_boot_cpus();
-   break;
-   case sparc_leon:
-   leon_boot_cpus();
-   break;
-   case sun4e:
-   printk("SUN4E\n");
-   BUG();
-   break;
-   case sun4u:
-   printk("SUN4U\n");
-   BUG();
-   break;
-   default:
-   printk("UNKNOWN!\n");
-   BUG();
-   break;
-   }
+   leon_boot_cpus();
 }
 
 /* Set this up early so that things like the scheduler can init
@@ -252,31 +208,7 @@ void __init smp_prepare_boot_cpu(void)
 
 int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-   int ret=0;
-
-   switch(sparc_cpu_model) {
-   case sun4m:
-   ret = smp4m_boot_one_cpu(cpu, tidle);
-   break;
-   case sun4d:
-   ret = smp4d_boot_one_cpu(cpu, tidle);
-   break;
-   case sparc_leon:
-   ret = leon_boot_one_cpu(cpu, tidle);
-   break;
-   case sun4e:
-   printk("SUN4E\n");
-   BUG();
-   break;
-   case sun4u:
-   printk("SUN4U\n");
-   BUG();
-   break;
-   default:
-   printk("UNKNOWN!\n");
-   BUG();
-   break;
-   }
+   int ret = leon_boot_one_cpu(cpu, tidle);
 
if (!ret) {
cpumask_set_cpu(cpu, _commenced_mask);
@@ -291,19 +223,7 @@ static void 

[PATCH 23/27] sparc32: Drop unused trampoline code

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Drop the sun4m and sun4d code from trampoline_32

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/kernel/kernel.h|   3 +-
 arch/sparc/kernel/trampoline_32.S | 127 +-
 2 files changed, 3 insertions(+), 127 deletions(-)

diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 30adbec894f7..aea96b6b881c 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -112,8 +112,7 @@ extern unsigned int real_irq_entry[];
 extern unsigned int smp4d_ticker[];
 
 /* trampoline_32.S */
-extern unsigned long sun4m_cpu_startup;
-extern unsigned long sun4d_cpu_startup;
+void leon_smp_cpu_startup(int boot_cpu);
 
 /* signal_32.c */
 asmlinkage void do_sigreturn(struct pt_regs *regs);
diff --git a/arch/sparc/kernel/trampoline_32.S 
b/arch/sparc/kernel/trampoline_32.S
index 82fafeeb3a62..685b20923f6b 100644
--- a/arch/sparc/kernel/trampoline_32.S
+++ b/arch/sparc/kernel/trampoline_32.S
@@ -15,136 +15,12 @@
 #include 
 #include 
 
-   .globl sun4m_cpu_startup
-   .globl sun4d_cpu_startup
-
-   .align 4
-
 /* When we start up a cpu for the first time it enters this routine.
  * This initializes the chip from whatever state the prom left it
  * in and sets PIL in %psr to 15, no irqs.
  */
-
-sun4m_cpu_startup:
-cpu1_startup:
-   sethi   %hi(trapbase_cpu1), %g3
-   b   1f
-or %g3, %lo(trapbase_cpu1), %g3
-
-cpu2_startup:
-   sethi   %hi(trapbase_cpu2), %g3
-   b   1f
-or %g3, %lo(trapbase_cpu2), %g3
-
-cpu3_startup:
-   sethi   %hi(trapbase_cpu3), %g3
-   b   1f
-or %g3, %lo(trapbase_cpu3), %g3
-
-1:
-   /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */
-   set (PSR_PIL | PSR_S | PSR_PS), %g1
-   wr  %g1, 0x0, %psr  ! traps off though
-   WRITE_PAUSE
-
-   /* Our %wim is one behind CWP */
-   mov 2, %g1
-   wr  %g1, 0x0, %wim
-   WRITE_PAUSE
-
-   /* This identifies "this cpu". */
-   wr  %g3, 0x0, %tbr
-   WRITE_PAUSE
-
-   /* Give ourselves a stack and curptr. */
-   set current_set, %g5
-   srl %g3, 10, %g4
-   and %g4, 0xc, %g4
-   ld  [%g5 + %g4], %g6
-
-   sethi   %hi(THREAD_SIZE - STACKFRAME_SZ), %sp
-   or  %sp, %lo(THREAD_SIZE - STACKFRAME_SZ), %sp
-   add %g6, %sp, %sp
-
-   /* Turn on traps (PSR_ET). */
-   rd  %psr, %g1
-   wr  %g1, PSR_ET, %psr   ! traps on
-   WRITE_PAUSE
-
-   /* Init our caches, etc. */
-   set poke_srmmu, %g5
-   ld  [%g5], %g5
-   call%g5
-nop
-
-   /* Start this processor. */
-   callsmp_callin
-nop
-
-   b,a smp_panic
-
.text
.align  4
-
-smp_panic:
-   callcpu_panic
-nop
-
-/* CPUID in bootbus can be found at PA 0xff014 */
-#define SUN4D_BOOTBUS_CPUID0xf014
-
-   .align  4
-
-sun4d_cpu_startup:
-   /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */
-   set (PSR_PIL | PSR_S | PSR_PS), %g1
-   wr  %g1, 0x0, %psr  ! traps off though
-   WRITE_PAUSE
-
-   /* Our %wim is one behind CWP */
-   mov 2, %g1
-   wr  %g1, 0x0, %wim
-   WRITE_PAUSE
-
-   /* Set tbr - we use just one trap table. */
-   set trapbase, %g1
-   wr  %g1, 0x0, %tbr
-   WRITE_PAUSE
-
-   /* Get our CPU id out of bootbus */
-   set SUN4D_BOOTBUS_CPUID, %g3
-   lduba   [%g3] ASI_M_CTL, %g3
-   and %g3, 0xf8, %g3
-   srl %g3, 3, %g1
-   sta %g1, [%g0] ASI_M_VIKING_TMP1
-
-   /* Give ourselves a stack and curptr. */
-   set current_set, %g5
-   srl %g3, 1, %g4
-   ld  [%g5 + %g4], %g6
-
-   sethi   %hi(THREAD_SIZE - STACKFRAME_SZ), %sp
-   or  %sp, %lo(THREAD_SIZE - STACKFRAME_SZ), %sp
-   add %g6, %sp, %sp
-
-   /* Turn on traps (PSR_ET). */
-   rd  %psr, %g1
-   wr  %g1, PSR_ET, %psr   ! traps on
-   WRITE_PAUSE
-
-   /* Init our caches, etc. */
-   set poke_srmmu, %g5
-   ld  [%g5], %g5
-   call%g5
-nop
-
-   /* Start this processor. */
-   callsmp_callin
-nop
-
-   b,a smp_panic
-
-   .align  4
 .global leon_smp_cpu_startup, smp_penguin_ctable
 
 leon_smp_cpu_startup:
@@ -198,4 +74,5 @@ leon_smp_cpu_startup:
callsmp_callin
 nop
 
-   b,a smp_panic
+   b,a cpu_panic
+nop

-- 
2.34.1



[PATCH 27/27] fbdev/p9100: Drop now unused driver p9100

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

The p9100 driver is only relevant for the Sparcbook 3 machine,
and with sun4m support removed this driver is no longer relevant.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
Cc: Helge Deller 
---
 drivers/video/fbdev/Kconfig  |   8 -
 drivers/video/fbdev/Makefile |   1 -
 drivers/video/fbdev/p9100.c  | 372 ---
 3 files changed, 381 deletions(-)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 94f6dca5856f..ebcc3815c7a5 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -576,14 +576,6 @@ config FB_CG14
  This is the frame buffer device driver for the CGfourteen frame
  buffer on Desktop SPARCsystems with the SX graphics option.
 
-config FB_P9100
-   bool "P9100 (Sparcbook 3 only) support"
-   depends on FB_SBUS
-   select FB_SBUS_HELPERS
-   help
- This is the frame buffer device driver for the P9100 card
- supported on Sparcbook 3 machines.
-
 config FB_LEO
bool "Leo (ZX) support"
depends on FB_SBUS
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 8e15220152bd..bc9b24648347 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -51,7 +51,6 @@ obj-$(CONFIG_FB_CG6)  += cg6.o
 obj-$(CONFIG_FB_CG3)  += cg3.o
 obj-$(CONFIG_FB_BW2)  += bw2.o
 obj-$(CONFIG_FB_CG14) += cg14.o
-obj-$(CONFIG_FB_P9100)+= p9100.o
 obj-$(CONFIG_FB_TCX)  += tcx.o
 obj-$(CONFIG_FB_LEO)  += leo.o
 obj-$(CONFIG_FB_ACORN)+= acornfb.o
diff --git a/drivers/video/fbdev/p9100.c b/drivers/video/fbdev/p9100.c
deleted file mode 100644
index e1356f8a866e..
--- a/drivers/video/fbdev/p9100.c
+++ /dev/null
@@ -1,372 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* p9100.c: P9100 frame buffer driver
- *
- * Copyright (C) 2003, 2006 David S. Miller (da...@davemloft.net)
- * Copyright 1999 Derrick J Brashear (sha...@dementia.org)
- *
- * Driver layout based loosely on tgafb.c, see that file for credits.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-
-#include "sbuslib.h"
-
-/*
- * Local functions.
- */
-
-static int p9100_setcolreg(unsigned, unsigned, unsigned, unsigned,
-  unsigned, struct fb_info *);
-static int p9100_blank(int, struct fb_info *);
-
-static int p9100_sbusfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
-static int p9100_sbusfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned 
long arg);
-
-/*
- *  Frame buffer operations
- */
-
-static const struct fb_ops p9100_ops = {
-   .owner  = THIS_MODULE,
-   FB_DEFAULT_SBUS_OPS(p9100),
-   .fb_setcolreg   = p9100_setcolreg,
-   .fb_blank   = p9100_blank,
-};
-
-/* P9100 control registers */
-#define P9100_SYSCTL_OFF   0x0UL
-#define P9100_VIDEOCTL_OFF 0x100UL
-#define P9100_VRAMCTL_OFF  0x180UL
-#define P9100_RAMDAC_OFF   0x200UL
-#define P9100_VIDEOCOPROC_OFF  0x400UL
-
-/* P9100 command registers */
-#define P9100_CMD_OFF 0x0UL
-
-/* P9100 framebuffer memory */
-#define P9100_FB_OFF 0x0UL
-
-/* 3 bits: 2=8bpp 3=16bpp 5=32bpp 7=24bpp */
-#define SYS_CONFIG_PIXELSIZE_SHIFT 26
-
-#define SCREENPAINT_TIMECTL1_ENABLE_VIDEO 0x20 /* 0 = off, 1 = on */
-
-struct p9100_regs {
-   /* Registers for the system control */
-   u32 sys_base;
-   u32 sys_config;
-   u32 sys_intr;
-   u32 sys_int_ena;
-   u32 sys_alt_rd;
-   u32 sys_alt_wr;
-   u32 sys_xxx[58];
-
-   /* Registers for the video control */
-   u32 vid_base;
-   u32 vid_hcnt;
-   u32 vid_htotal;
-   u32 vid_hsync_rise;
-   u32 vid_hblank_rise;
-   u32 vid_hblank_fall;
-   u32 vid_hcnt_preload;
-   u32 vid_vcnt;
-   u32 vid_vlen;
-   u32 vid_vsync_rise;
-   u32 vid_vblank_rise;
-   u32 vid_vblank_fall;
-   u32 vid_vcnt_preload;
-   u32 vid_screenpaint_addr;
-   u32 vid_screenpaint_timectl1;
-   u32 vid_screenpaint_qsfcnt;
-   u32 vid_screenpaint_timectl2;
-   u32 vid_xxx[15];
-
-   /* Registers for the video control */
-   u32 vram_base;
-   u32 vram_memcfg;
-   u32 vram_refresh_pd;
-   u32 vram_refresh_cnt;
-   u32 vram_raslo_max;
-   u32 vram_raslo_cur;
-   u32 pwrup_cfg;
-   u32 vram_xxx[25];
-
-   /* Registers for IBM RGB528 Palette */
-   u32 ramdac_cmap_wridx;
-   u32 ramdac_palette_data;
-   u32 ramdac_pixel_mask;
-   u32 ramdac_palette_rdaddr;
-   u32 ramdac_idx_lo;
-   u32 ramdac_idx_hi;
-   u32 ramdac_idx_data;
-   u32 ramdac_idx_ctl;
-   u32 ramdac_xxx[1784];
-};
-
-struct p9100_cmd_parameng {
-   u32 parameng_status;
-   u32 parameng_bltcmd;
-   u32 

[PATCH 17/27] sparc32: Drop run-time patching of ASI instructions

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

With only LEON supported there is no need to run-time patch
the instructions to match ASI.

Move a few functions back to C with inline asm, now that
run-time patching is not needed.

Deleted a few functions that turns out not to be used rather
than re-implement them in C.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/asmmacro.h | 22 ---
 arch/sparc/include/asm/pgtsrmmu.h | 29 +++---
 arch/sparc/include/asm/sections.h |  3 --
 arch/sparc/include/asm/winmacro.h | 11 +-
 arch/sparc/kernel/entry.S |  7 +---
 arch/sparc/kernel/etrap_32.S  | 15 +++
 arch/sparc/kernel/rtrap_32.S  | 18 +++--
 arch/sparc/kernel/setup_32.c  | 37 -
 arch/sparc/kernel/vmlinux.lds.S   |  5 ---
 arch/sparc/kernel/wof.S   | 18 +++--
 arch/sparc/kernel/wuf.S   | 21 --
 arch/sparc/mm/Makefile|  1 -
 arch/sparc/mm/srmmu_access.S  | 83 ---
 13 files changed, 43 insertions(+), 227 deletions(-)

diff --git a/arch/sparc/include/asm/asmmacro.h 
b/arch/sparc/include/asm/asmmacro.h
index 49aaf6f3bc55..d5782dbc7810 100644
--- a/arch/sparc/include/asm/asmmacro.h
+++ b/arch/sparc/include/asm/asmmacro.h
@@ -21,26 +21,4 @@
 /* All traps low-level code here must end with this macro. */
 #define RESTORE_ALL b ret_trap_entry; clr %l6;
 
-/* Support for run-time patching of single instructions.
- * This is used to handle the differences in the ASI for
- * MMUREGS for LEON and SUN.
- *
- * Sample:
- * LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0
- * SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0
- * PI == Patch Instruction
- *
- * For LEON we will use the first variant,
- * and for all other we will use the SUN variant.
- * The order is important.
- */
-#define LEON_PI(...)   \
-662:   __VA_ARGS__
-
-#define SUN_PI_(...)   \
-   .section .leon_1insn_patch, "ax";   \
-   .word 662b; \
-   __VA_ARGS__;\
-   .previous
-
 #endif /* !(_SPARC_ASMMACRO_H) */
diff --git a/arch/sparc/include/asm/pgtsrmmu.h 
b/arch/sparc/include/asm/pgtsrmmu.h
index 664d4bba1bcb..69c28ff3c4c4 100644
--- a/arch/sparc/include/asm/pgtsrmmu.h
+++ b/arch/sparc/include/asm/pgtsrmmu.h
@@ -107,23 +107,24 @@ extern void *srmmu_nocache_pool;
 #define __nocache_va(PADDR) (__va((unsigned long)PADDR) - (unsigned 
long)srmmu_nocache_pool + SRMMU_NOCACHE_VADDR)
 #define __nocache_fix(VADDR) ((__typeof__(VADDR))__va(__nocache_pa(VADDR)))
 
-/* Accessing the MMU control register. */
-unsigned int srmmu_get_mmureg(void);
-void srmmu_set_mmureg(unsigned long regval);
-void srmmu_set_ctable_ptr(unsigned long paddr);
-void srmmu_set_context(int context);
-int srmmu_get_context(void);
-unsigned int srmmu_get_fstatus(void);
-unsigned int srmmu_get_faddr(void);
-
-/* This is guaranteed on all SRMMU's. */
-static inline void srmmu_flush_whole_tlb(void)
+static inline void srmmu_set_ctable_ptr(unsigned long paddr)
 {
-   __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
-"r" (0x400),/* Flush entire TLB!! */
-"i" (ASI_M_FLUSH_PROBE) : "memory");
+   paddr = ((paddr >> 4) & SRMMU_CTX_PMASK);
+   asm volatile("sta %0, [%1] %2\n\t" : : "r" (paddr), "r" 
(SRMMU_CTXTBL_PTR), "i" (ASI_LEON_MMUREGS) : "memory");
+}
+
+static inline void srmmu_set_context(int context)
+{
+   asm volatile("sta %0, [%1] %2\n\t" : : "r" (context), "r" 
(SRMMU_CTX_REG), "i" (ASI_LEON_MMUREGS) : "memory");
+}
 
+static inline int srmmu_get_context(void)
+{
+   register int retval;
+   asm volatile("lda [%1] %2, %0\n\t" : "=r" (retval) : "r" 
(SRMMU_CTX_REG), "i" (ASI_LEON_MMUREGS));
+   return retval;
 }
+
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(_SPARC_PGTSRMMU_H) */
diff --git a/arch/sparc/include/asm/sections.h 
b/arch/sparc/include/asm/sections.h
index 08f833453ab3..e9d28148850b 100644
--- a/arch/sparc/include/asm/sections.h
+++ b/arch/sparc/include/asm/sections.h
@@ -8,7 +8,4 @@
 /* sparc entry point */
 extern char _start[];
 
-extern char __leon_1insn_patch[];
-extern char __leon_1insn_patch_end[];
-
 #endif
diff --git a/arch/sparc/include/asm/winmacro.h 
b/arch/sparc/include/asm/winmacro.h
index b6e911f5d93c..c496b04cdfaf 100644
--- a/arch/sparc/include/asm/winmacro.h
+++ b/arch/sparc/include/asm/winmacro.h
@@ -108,18 +108,11 @@
 661:   rd  %tbr, %idreg;   \
srl %idreg, 10, %idreg; \
and %idreg, 0xc, %idreg;\
-   .section.cpuid_patch, "ax"; \
-   /* Instruction location. */ \
-   .word   661b;   \
-   /* SUN4D implementation. */ \
-   lda  [%g0] ASI_M_VIKING_TMP1, %idreg;   \
-   sll  

[PATCH 00/27] sparc32: sunset sun4m and sun4d

2023-12-19 Thread Sam Ravnborg via B4 Relay
/winmacro.h |  11 +-
 arch/sparc/kernel/Makefile|   8 +-
 arch/sparc/kernel/apc.c   | 196 
 arch/sparc/kernel/auxio_32.c  | 139 --
 arch/sparc/kernel/cpu.c   |   1 -
 arch/sparc/kernel/devices.c   |  10 +-
 arch/sparc/kernel/entry.S | 413 +
 arch/sparc/kernel/etrap_32.S  |  50 +-
 arch/sparc/kernel/head_32.S   | 255 +--
 arch/sparc/kernel/ioport.c|  55 +--
 arch/sparc/kernel/irq.h   |  85 +---
 arch/sparc/kernel/irq_32.c| 133 +-
 arch/sparc/kernel/kernel.h|  53 +--
 arch/sparc/kernel/led.c   | 146 --
 arch/sparc/kernel/leon_kernel.c   |  53 +--
 arch/sparc/kernel/leon_pmc.c  |  16 +-
 arch/sparc/kernel/leon_smp.c  |   3 -
 arch/sparc/kernel/of_device_32.c  |  18 +-
 arch/sparc/kernel/pcic.c  | 840 --
 arch/sparc/kernel/pmc.c   | 100 
 arch/sparc/kernel/process_32.c|  10 -
 arch/sparc/kernel/rtrap_32.S  |  73 ++-
 arch/sparc/kernel/setup_32.c  | 115 -
 arch/sparc/kernel/smp_32.c| 102 +
 arch/sparc/kernel/sun4d_irq.c | 519 -
 arch/sparc/kernel/sun4d_smp.c | 415 -
 arch/sparc/kernel/sun4m_irq.c | 478 ---
 arch/sparc/kernel/sun4m_smp.c | 275 ---
 arch/sparc/kernel/time_32.c   |  68 +--
 arch/sparc/kernel/trampoline_32.S | 127 +
 arch/sparc/kernel/ttable_32.S |   9 +-
 arch/sparc/kernel/vmlinux.lds.S   |   5 -
 arch/sparc/kernel/wof.S   |  61 +--
 arch/sparc/kernel/wuf.S   |  41 +-
 arch/sparc/mm/Makefile|   4 +-
 arch/sparc/mm/hypersparc.S| 414 -
 arch/sparc/mm/io-unit.c   | 286 
 arch/sparc/mm/iommu.c | 455 --
 arch/sparc/mm/mm_32.h |   4 -
 arch/sparc/mm/srmmu.c | 836 +
 arch/sparc/mm/srmmu_access.S  |  83 
 arch/sparc/mm/swift.S | 256 ---
 arch/sparc/mm/tsunami.S   | 132 --
 arch/sparc/mm/viking.S| 284 
 arch/sparc/prom/Makefile  |   1 -
 arch/sparc/prom/init_32.c |   2 -
 arch/sparc/prom/misc_32.c |   2 -
 arch/sparc/prom/ranges.c  | 114 -
 drivers/sbus/char/Kconfig |   8 -
 drivers/sbus/char/Makefile|   1 -
 drivers/sbus/char/uctrl.c | 435 --
 drivers/usb/host/Kconfig  |   2 +-
 drivers/usb/host/ehci-hcd.c   |   4 +-
 drivers/usb/host/uhci-hcd.c   |   2 +-
 drivers/video/fbdev/Kconfig   |  10 +-
 drivers/video/fbdev/Makefile  |   1 -
 drivers/video/fbdev/p9100.c   | 372 ---
 sound/sparc/Kconfig   |   1 +
 88 files changed, 318 insertions(+), 10809 deletions(-)
---
base-commit: bee0e7762ad2c6025b9f5245c040fcc36ef2bde8
change-id: 20231219-sam-sparc32-sunset-v3-4751ea89da2d

Best regards,
-- 
Sam Ravnborg 



[PATCH 21/27] sparc32: Drop unused iommu support

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

LEON do not have any iommu support - drop it.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/iommu.h|   2 -
 arch/sparc/include/asm/iommu_32.h | 122 ---
 arch/sparc/kernel/ioport.c|   1 -
 arch/sparc/mm/Makefile|   2 +-
 arch/sparc/mm/iommu.c | 420 --
 arch/sparc/mm/mm_32.h |   3 -
 arch/sparc/mm/srmmu.c |   3 -
 7 files changed, 1 insertion(+), 552 deletions(-)

diff --git a/arch/sparc/include/asm/iommu.h b/arch/sparc/include/asm/iommu.h
index 37935cb34865..ea07526ff476 100644
--- a/arch/sparc/include/asm/iommu.h
+++ b/arch/sparc/include/asm/iommu.h
@@ -3,7 +3,5 @@
 #define ___ASM_SPARC_IOMMU_H
 #if defined(__sparc__) && defined(__arch64__)
 #include 
-#else
-#include 
 #endif
 #endif
diff --git a/arch/sparc/include/asm/iommu_32.h 
b/arch/sparc/include/asm/iommu_32.h
deleted file mode 100644
index af51cd5ea3c1..
--- a/arch/sparc/include/asm/iommu_32.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* iommu.h: Definitions for the sun4m IOMMU.
- *
- * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
- */
-#ifndef _SPARC_IOMMU_H
-#define _SPARC_IOMMU_H
-
-#include 
-#include 
-
-/* The iommu handles all virtual to physical address translations
- * that occur between the SBUS and physical memory.  Access by
- * the cpu to IO registers and similar go over the mbus so are
- * translated by the on chip SRMMU.  The iommu and the srmmu do
- * not need to have the same translations at all, in fact most
- * of the time the translations they handle are a disjunct set.
- * Basically the iommu handles all dvma sbus activity.
- */
-
-/* The IOMMU registers occupy three pages in IO space. */
-struct iommu_regs {
-   /* First page */
-   volatile unsigned long control;/* IOMMU control */
-   volatile unsigned long base;   /* Physical base of iopte page table 
*/
-   volatile unsigned long _unused1[3];
-   volatile unsigned long tlbflush;   /* write only */
-   volatile unsigned long pageflush;  /* write only */
-   volatile unsigned long _unused2[1017];
-   /* Second page */
-   volatile unsigned long afsr;   /* Async-fault status register */
-   volatile unsigned long afar;   /* Async-fault physical address */
-   volatile unsigned long _unused3[2];
-   volatile unsigned long sbuscfg0;   /* SBUS configuration registers, 
per-slot */
-   volatile unsigned long sbuscfg1;
-   volatile unsigned long sbuscfg2;
-   volatile unsigned long sbuscfg3;
-   volatile unsigned long mfsr;   /* Memory-fault status register */
-   volatile unsigned long mfar;   /* Memory-fault physical address */
-   volatile unsigned long _unused4[1014];
-   /* Third page */
-   volatile unsigned long mid;/* IOMMU module-id */
-};
-
-#define IOMMU_CTRL_IMPL 0xf000 /* Implementation */
-#define IOMMU_CTRL_VERS 0x0f00 /* Version */
-#define IOMMU_CTRL_RNGE 0x001c /* Mapping RANGE */
-#define IOMMU_RNGE_16MB 0x /* 0xff00 -> 0x */
-#define IOMMU_RNGE_32MB 0x0004 /* 0xfe00 -> 0x */
-#define IOMMU_RNGE_64MB 0x0008 /* 0xfc00 -> 0x */
-#define IOMMU_RNGE_128MB0x000c /* 0xf800 -> 0x */
-#define IOMMU_RNGE_256MB0x0010 /* 0xf000 -> 0x */
-#define IOMMU_RNGE_512MB0x0014 /* 0xe000 -> 0x */
-#define IOMMU_RNGE_1GB  0x0018 /* 0xc000 -> 0x */
-#define IOMMU_RNGE_2GB  0x001c /* 0x8000 -> 0x */
-#define IOMMU_CTRL_ENAB 0x0001 /* IOMMU Enable */
-
-#define IOMMU_AFSR_ERR  0x8000 /* LE, TO, or BE asserted */
-#define IOMMU_AFSR_LE   0x4000 /* SBUS reports error after transaction 
*/
-#define IOMMU_AFSR_TO   0x2000 /* Write access took more than 12.8 us. 
*/
-#define IOMMU_AFSR_BE   0x1000 /* Write access received error 
acknowledge */
-#define IOMMU_AFSR_SIZE 0x0e00 /* Size of transaction causing error */
-#define IOMMU_AFSR_S0x0100 /* Sparc was in supervisor mode */
-#define IOMMU_AFSR_RESV 0x00f0 /* Reserver, forced to 0x8 by hardware 
*/
-#define IOMMU_AFSR_ME   0x0008 /* Multiple errors occurred */
-#define IOMMU_AFSR_RD   0x0004 /* A read operation was in progress */
-#define IOMMU_AFSR_FAV  0x0002 /* IOMMU afar has valid contents */
-
-#define IOMMU_SBCFG_SAB30   0x0001 /* Phys-address bit 30 when bypass 
enabled */
-#define IOMMU_SBCFG_BA160x0004 /* Slave supports 16 byte bursts */
-#define IOMMU_SBCFG_BA8 0x0002 /* Slave supports 8 byte bursts */
-#define IOMMU_SBCFG_BYPASS  0x0001 /* Bypass IOMMU, treat all addresses
- produced by this device as pure
-  

[PATCH 15/27] sparc32: Drop check for sparc_model

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

sparc32 is always LEON, so no need to check for the model.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/cpu_type.h | 18 -
 arch/sparc/include/asm/io_32.h|  4 +-
 arch/sparc/include/asm/pgtsrmmu.h |  1 -
 arch/sparc/kernel/devices.c   |  7 +---
 arch/sparc/kernel/ioport.c|  4 +-
 arch/sparc/kernel/leon_pmc.c  | 16 
 arch/sparc/kernel/setup_32.c  | 79 +--
 7 files changed, 12 insertions(+), 117 deletions(-)

diff --git a/arch/sparc/include/asm/cpu_type.h 
b/arch/sparc/include/asm/cpu_type.h
index 2b59799859d1..3e0154c3f41d 100644
--- a/arch/sparc/include/asm/cpu_type.h
+++ b/arch/sparc/include/asm/cpu_type.h
@@ -2,28 +2,10 @@
 #ifndef __ASM_CPU_TYPE_H
 #define __ASM_CPU_TYPE_H
 
-/*
- * Sparc (general) CPU types
- */
-enum sparc_cpu {
-  sun4m   = 0x00,
-  sun4d   = 0x01,
-  sun4e   = 0x02,
-  sun4u   = 0x03, /* V8 ploos ploos */
-  sun_unknown = 0x04,
-  ap1000  = 0x05, /* almost a sun4m */
-  sparc_leon  = 0x06, /* Leon SoC */
-};
-
 #ifdef CONFIG_SPARC32
-extern enum sparc_cpu sparc_cpu_model;
 
 #define SUN4M_NCPUS4  /* Architectural limit of sun4m. 
*/
 
-#else
-
-#define sparc_cpu_model sun4u
-
 #endif
 
 #endif /* __ASM_CPU_TYPE_H */
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 549f0a72280d..83abe709d120 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -138,11 +138,11 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *);
 
 static inline int sbus_can_dma_64bit(void)
 {
-   return 0; /* actually, sparc_cpu_model==sun4d */
+   return 0;
 }
 static inline int sbus_can_burst64(void)
 {
-   return 0; /* actually, sparc_cpu_model==sun4d */
+   return 0;
 }
 struct device;
 void sbus_set_sbus64(struct device *, int);
diff --git a/arch/sparc/include/asm/pgtsrmmu.h 
b/arch/sparc/include/asm/pgtsrmmu.h
index 7cb5cbc83211..664d4bba1bcb 100644
--- a/arch/sparc/include/asm/pgtsrmmu.h
+++ b/arch/sparc/include/asm/pgtsrmmu.h
@@ -124,7 +124,6 @@ static inline void srmmu_flush_whole_tlb(void)
 "i" (ASI_M_FLUSH_PROBE) : "memory");
 
 }
-
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(_SPARC_PGTSRMMU_H) */
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c
index b3c2d51b22c4..2963e89611a3 100644
--- a/arch/sparc/kernel/devices.c
+++ b/arch/sparc/kernel/devices.c
@@ -26,8 +26,6 @@
 
 static char *cpu_mid_prop(void)
 {
-   if (sparc_cpu_model == sun4d)
-   return "cpu-id";
return "mid";
 }
 
@@ -40,8 +38,6 @@ static int check_cpu_node(phandle nd, int *cur_inst,
*prom_node = nd;
if (mid) {
*mid = prom_getintdefault(nd, cpu_mid_prop(), 0);
-   if (sparc_cpu_model == sun4m)
-   *mid &= 3;
}
return 0;
}
@@ -92,8 +88,7 @@ static int cpu_mid_compare(phandle nd, int instance, void 
*_arg)
int this_mid;
 
this_mid = prom_getintdefault(nd, cpu_mid_prop(), 0);
-   if (this_mid == desired_mid
-   || (sparc_cpu_model == sun4m && (this_mid & 3) == desired_mid))
+   if (this_mid == desired_mid)
return 0;
return -ENODEV;
 }
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 5ebca5c7af1e..cf0ace29704a 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -309,9 +309,7 @@ arch_initcall(sparc_register_ioport);
 void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
enum dma_data_direction dir)
 {
-   if (dir != DMA_TO_DEVICE &&
-   sparc_cpu_model == sparc_leon &&
-   !sparc_leon3_snooping_enabled())
+   if (dir != DMA_TO_DEVICE && !sparc_leon3_snooping_enabled())
leon_flush_dcache_all();
 }
 
diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c
index 6c00cbad7fb5..d4a2d49f941c 100644
--- a/arch/sparc/kernel/leon_pmc.c
+++ b/arch/sparc/kernel/leon_pmc.c
@@ -79,15 +79,13 @@ static void pmc_leon_idle(void)
 /* Install LEON Power Down function */
 static int __init leon_pmc_install(void)
 {
-   if (sparc_cpu_model == sparc_leon) {
-   /* Assign power management IDLE handler */
-   if (pmc_leon_need_fixup())
-   sparc_idle = pmc_leon_idle_fixup;
-   else
-   sparc_idle = pmc_leon_idle;
-
-   printk(KERN_INFO "leon: power management initialized\n");
-   }
+   /* Assign power management IDLE handler */
+   if (pmc_leon_need_fixup())
+   sparc_idle = pmc_leon_idle_fixup;
+   else
+   sparc_idle = pmc_leon_idle;
+
+   printk(KERN_INFO "leon: power management initialized\n");
 
return 0;
 }
diff --git 

[PATCH 18/27] sparc32: Drop support for 7 register windows

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Some older SPARC CPUs had support for only 7 register windows.
To support this run-time patching was used.

LEON demand 8 register windows for use with Linux so
there is no need to support the 7 window configuration.

The complexity of the assembler code is reduced
when dropping the run-time patching, thus increasing
the maintainability.

Signed-off-by: Sam Ravnborg 
Cc: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/switch_to_32.h |  1 -
 arch/sparc/kernel/entry.S | 28 ---
 arch/sparc/kernel/etrap_32.S  | 35 +--
 arch/sparc/kernel/head_32.S   | 65 ---
 arch/sparc/kernel/rtrap_32.S  | 55 +
 arch/sparc/kernel/wof.S   | 43 ---
 arch/sparc/kernel/wuf.S   | 20 +++
 7 files changed, 57 insertions(+), 190 deletions(-)

diff --git a/arch/sparc/include/asm/switch_to_32.h 
b/arch/sparc/include/asm/switch_to_32.h
index 42eeafcb8a41..7aaaf31c09b4 100644
--- a/arch/sparc/include/asm/switch_to_32.h
+++ b/arch/sparc/include/asm/switch_to_32.h
@@ -37,7 +37,6 @@ extern struct thread_info *current_set[NR_CPUS];
 
 #define prepare_arch_switch(next) do { \
__asm__ __volatile__( \
-   ".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \
"save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
"save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
"save %sp, -0x40, %sp\n\t" \
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 9cf8f87e8c42..078a8f7f8383 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -384,11 +384,8 @@ do_flush_windows:
 
RESTORE_ALL
 
-   .globl  flush_patch_one
-
/* We get these for debugging routines using __builtin_return_address() 
*/
 dfw_kernel:
-flush_patch_one:
FLUSH_ALL_KERNEL_WINDOWS
 
/* Advance over the trap instruction. */
@@ -558,10 +555,9 @@ sys_rt_sigreturn:
 * XXX code just like on sparc64... -DaveM
 */
.align  4
-   .globl  sys_fork, flush_patch_two
+   .globl  sys_fork
 sys_fork:
mov %o7, %l5
-flush_patch_two:
FLUSH_ALL_KERNEL_WINDOWS;
ld  [%curptr + TI_TASK], %o4
rd  %psr, %g4
@@ -574,10 +570,9 @@ flush_patch_two:
 mov%l5, %o7
 
/* Whee, kernel threads! */
-   .globl  sys_clone, flush_patch_three
+   .globl  sys_clone
 sys_clone:
mov %o7, %l5
-flush_patch_three:
FLUSH_ALL_KERNEL_WINDOWS;
ld  [%curptr + TI_TASK], %o4
rd  %psr, %g4
@@ -590,9 +585,8 @@ flush_patch_three:
 mov%l5, %o7
 
/* Whee, real vfork! */
-   .globl  sys_vfork, flush_patch_four
+   .globl  sys_vfork
 sys_vfork:
-flush_patch_four:
FLUSH_ALL_KERNEL_WINDOWS;
ld  [%curptr + TI_TASK], %o4
rd  %psr, %g4
@@ -909,17 +903,7 @@ breakpoint_trap:
 #endif
 
.align  4
-   .globl  flush_patch_exception
-flush_patch_exception:
-   FLUSH_ALL_KERNEL_WINDOWS;
-   ldd [%o0], %o6
-   jmpl%o7 + 0xc, %g0  ! see asm-sparc/processor.h
-mov1, %g1  ! signal EFAULT condition
-
-   .align  4
-   .globl  kill_user_windows, kuw_patch1_7win
-   .globl  kuw_patch1
-kuw_patch1_7win:   sll %o3, 6, %o3
+   .globl  kill_user_windows
 
/* No matter how much overhead this routine has in the worst
 * case scenario, it is several times better than taking the
@@ -939,11 +923,11 @@ kill_user_windows:
be  4f  ! yep, we are done
 rd %wim, %o3   ! get current wim
srl %o3, 1, %o4 ! simulate a save
-kuw_patch1:
+kuw_next:
sll %o3, 7, %o3 ! compute next wim
or  %o4, %o3, %o3   ! result
andncc  %o0, %o3, %o0   ! clean this bit in umask
-   bne kuw_patch1  ! not done yet
+   bne kuw_next! not done yet
 srl%o3, 1, %o4 ! begin another save simulation
wr  %o3, 0x0, %wim  ! set the new wim
st  %g0, [%g6 + TI_UWINMASK]! clear uwinmask
diff --git a/arch/sparc/kernel/etrap_32.S b/arch/sparc/kernel/etrap_32.S
index bb222459f097..95dfdea1f36c 100644
--- a/arch/sparc/kernel/etrap_32.S
+++ b/arch/sparc/kernel/etrap_32.S
@@ -30,18 +30,6 @@
.text
.align 4
 
-   /* SEVEN WINDOW PATCH INSTRUCTIONS */
-   .globl  tsetup_7win_patch1, tsetup_7win_patch2
-   .globl  tsetup_7win_patch3, tsetup_7win_patch4
-   .globl  tsetup_7win_patch5, tsetup_7win_patch6
-tsetup_7win_patch1:sll %t_wim, 0x6, %t_wim
-tsetup_7win_patch2:   

[PATCH 05/27] sparc32: Drop sun specific power management drivers

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Drop the two sun specific apc and pmc drivers.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/Kconfig |   7 --
 arch/sparc/kernel/Makefile |   1 -
 arch/sparc/kernel/apc.c| 196 -
 arch/sparc/kernel/pmc.c| 100 ---
 4 files changed, 304 deletions(-)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 1520f68e944a..55a9e67c482e 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -324,13 +324,6 @@ config CMDLINE
 
  NOTE: This option WILL override the PROM bootargs setting!
 
-config SUN_PM
-   bool
-   default y if SPARC32
-   help
- Enable power management and CPU standby features on supported
- SPARC platforms.
-
 config SERIAL_CONSOLE
bool
depends on SPARC32
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 95687af45d20..ab47823f8b4e 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -84,7 +84,6 @@ obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o 
leon_smp.o
 obj-$(CONFIG_SPARC64_SMP) += hvtramp.o
 
 obj-y += auxio_$(BITS).o
-obj-$(CONFIG_SUN_PM)  += apc.o pmc.o
 
 obj-y += termios.o
 
diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c
deleted file mode 100644
index d44725d37e30..
--- a/arch/sparc/kernel/apc.c
+++ /dev/null
@@ -1,196 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* apc - Driver implementation for power management functions
- * of Aurora Personality Chip (APC) on SPARCstation-4/5 and
- * derivatives.
- *
- * Copyright (c) 2002 Eric Brower (ebro...@usa.net)
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-/* Debugging
- * 
- * #define APC_DEBUG_LED
- */
-
-#define APC_MINOR  MISC_DYNAMIC_MINOR
-#define APC_OBPNAME"power-management"
-#define APC_DEVNAME "apc"
-
-static u8 __iomem *regs;
-static int apc_no_idle = 0;
-
-#define apc_readb(offs)(sbus_readb(regs+offs))
-#define apc_writeb(val, offs)  (sbus_writeb(val, regs+offs))
-
-/* Specify "apc=noidle" on the kernel command line to 
- * disable APC CPU standby support.  Certain prototype
- * systems (SPARCstation-Fox) do not play well with APC
- * CPU idle, so disable this if your system has APC and 
- * crashes randomly.
- */
-static int __init apc_setup(char *str) 
-{
-   if(!strncmp(str, "noidle", strlen("noidle"))) {
-   apc_no_idle = 1;
-   return 1;
-   }
-   return 0;
-}
-__setup("apc=", apc_setup);
-
-/* 
- * CPU idle callback function
- * See .../arch/sparc/kernel/process.c
- */
-static void apc_swift_idle(void)
-{
-#ifdef APC_DEBUG_LED
-   set_auxio(0x00, AUXIO_LED); 
-#endif
-
-   apc_writeb(apc_readb(APC_IDLE_REG) | APC_IDLE_ON, APC_IDLE_REG);
-
-#ifdef APC_DEBUG_LED
-   set_auxio(AUXIO_LED, 0x00); 
-#endif
-} 
-
-static inline void apc_free(struct platform_device *op)
-{
-   of_iounmap(>resource[0], regs, resource_size(>resource[0]));
-}
-
-static int apc_open(struct inode *inode, struct file *f)
-{
-   return 0;
-}
-
-static int apc_release(struct inode *inode, struct file *f)
-{
-   return 0;
-}
-
-static long apc_ioctl(struct file *f, unsigned int cmd, unsigned long __arg)
-{
-   __u8 inarg, __user *arg = (__u8 __user *) __arg;
-
-   switch (cmd) {
-   case APCIOCGFANCTL:
-   if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg))
-   return -EFAULT;
-   break;
-
-   case APCIOCGCPWR:
-   if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg))
-   return -EFAULT;
-   break;
-
-   case APCIOCGBPORT:
-   if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg))
-   return -EFAULT;
-   break;
-
-   case APCIOCSFANCTL:
-   if (get_user(inarg, arg))
-   return -EFAULT;
-   apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG);
-   break;
-
-   case APCIOCSCPWR:
-   if (get_user(inarg, arg))
-   return -EFAULT;
-   apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG);
-   break;
-
-   case APCIOCSBPORT:
-   if (get_user(inarg, arg))
-   return -EFAULT;
-   apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG);
-   break;
-
-   default:
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
-static const struct file_operations apc_fops = {
-   .unlocked_ioctl =   apc_ioctl,
-   .open = apc_open,
-   .release =  apc_release,
-   .llseek =   noop_llseek,
-};
-
-static struct miscdevice 

[PATCH 25/27] sparc32: Drop sbus support

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

LEON do not have an sbus - so drop support for that for sparc32.
Fix a few Kconfig expressions to use CONFIG_SBUS rather than SPARC
as only SPARC64 has an sbus now.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/Kconfig   |  4 +-
 arch/sparc/include/asm/fb.h  |  8 ++--
 arch/sparc/include/asm/io_32.h   | 83 
 arch/sparc/kernel/ioport.c   | 49 
 arch/sparc/kernel/of_device_32.c | 14 ---
 drivers/video/fbdev/Kconfig  |  2 +-
 sound/sparc/Kconfig  |  1 +
 7 files changed, 9 insertions(+), 152 deletions(-)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 0fc52c3c7487..1b9cf7f3c500 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -392,11 +392,11 @@ endmenu
 menu "Bus options (PCI etc.)"
 config SBUS
bool
-   default y
+   default y if SPARC64
 
 config SBUSCHAR
bool
-   default y
+   default y if SPARC64
 
 config SUN_LDOMS
bool "Sun Logical Domains support"
diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h
index 24440c0fda49..15b007875457 100644
--- a/arch/sparc/include/asm/fb.h
+++ b/arch/sparc/include/asm/fb.h
@@ -8,6 +8,9 @@
 
 struct fb_info;
 
+int fb_is_primary_device(struct fb_info *info);
+#define fb_is_primary_device fb_is_primary_device
+
 #ifdef CONFIG_SPARC32
 static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
  unsigned long vm_start, unsigned long 
vm_end,
@@ -18,9 +21,7 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
 #define pgprot_framebuffer pgprot_framebuffer
 #endif
 
-int fb_is_primary_device(struct fb_info *info);
-#define fb_is_primary_device fb_is_primary_device
-
+#ifdef CONFIG_SPARC64
 static inline void fb_memcpy_fromio(void *to, const volatile void __iomem 
*from, size_t n)
 {
sbus_memcpy_fromio(to, from, n);
@@ -38,6 +39,7 @@ static inline void fb_memset_io(volatile void __iomem *addr, 
int c, size_t n)
sbus_memset_io(addr, c, n);
 }
 #define fb_memset fb_memset_io
+#endif
 
 #include 
 
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 83abe709d120..b9f280ee1b11 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -56,78 +56,6 @@ static inline void _memcpy_toio(volatile void __iomem *dst, 
const void *src,
}
 }
 
-/*
- * SBus accessors.
- *
- * SBus has only one, memory mapped, I/O space.
- * We do not need to flip bytes for SBus of course.
- */
-static inline u8 sbus_readb(const volatile void __iomem *addr)
-{
-   return *(__force volatile u8 *)addr;
-}
-
-static inline u16 sbus_readw(const volatile void __iomem *addr)
-{
-   return *(__force volatile u16 *)addr;
-}
-
-static inline u32 sbus_readl(const volatile void __iomem *addr)
-{
-   return *(__force volatile u32 *)addr;
-}
-
-static inline void sbus_writeb(u8 b, volatile void __iomem *addr)
-{
-   *(__force volatile u8 *)addr = b;
-}
-
-static inline void sbus_writew(u16 w, volatile void __iomem *addr)
-{
-   *(__force volatile u16 *)addr = w;
-}
-
-static inline void sbus_writel(u32 l, volatile void __iomem *addr)
-{
-   *(__force volatile u32 *)addr = l;
-}
-
-static inline void sbus_memset_io(volatile void __iomem *__dst, int c,
-  __kernel_size_t n)
-{
-   while(n--) {
-   sbus_writeb(c, __dst);
-   __dst++;
-   }
-}
-
-static inline void sbus_memcpy_fromio(void *dst,
-  const volatile void __iomem *src,
-  __kernel_size_t n)
-{
-   char *d = dst;
-
-   while (n--) {
-   char tmp = sbus_readb(src);
-   *d++ = tmp;
-   src++;
-   }
-}
-
-static inline void sbus_memcpy_toio(volatile void __iomem *dst,
-const void *src,
-__kernel_size_t n)
-{
-   const char *s = src;
-   volatile void __iomem *d = dst;
-
-   while (n--) {
-   char tmp = *s++;
-   sbus_writeb(tmp, d);
-   d++;
-   }
-}
-
 /* Create a virtual mapping cookie for an IO port range */
 void __iomem *ioport_map(unsigned long port, unsigned int nr);
 void ioport_unmap(void __iomem *);
@@ -136,17 +64,6 @@ void ioport_unmap(void __iomem *);
 struct pci_dev;
 void pci_iounmap(struct pci_dev *dev, void __iomem *);
 
-static inline int sbus_can_dma_64bit(void)
-{
-   return 0;
-}
-static inline int sbus_can_burst64(void)
-{
-   return 0;
-}
-struct device;
-void sbus_set_sbus64(struct device *, int);
-
 #define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1
 
 
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 9c4c72775274..97b836f3be25 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c

[PATCH 26/27] sbus: char: Drop now unused uctrl driver

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

The uctrl driver is only relevant for the Sparcbook 3 machine,
and with sun4m support removed this driver is no logner relevant.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 drivers/sbus/char/Kconfig  |   8 -
 drivers/sbus/char/Makefile |   1 -
 drivers/sbus/char/uctrl.c  | 435 -
 3 files changed, 444 deletions(-)

diff --git a/drivers/sbus/char/Kconfig b/drivers/sbus/char/Kconfig
index 7c0a308e4959..8b80abc554ed 100644
--- a/drivers/sbus/char/Kconfig
+++ b/drivers/sbus/char/Kconfig
@@ -21,14 +21,6 @@ config OBP_FLASH
  The OpenBoot PROM on Ultra systems is flashable. If you want to be
  able to upgrade the OBP firmware, say Y here.
 
-config TADPOLE_TS102_UCTRL
-   tristate "Tadpole TS102 Microcontroller support"
-   help
- Say Y here to directly support the TS102 Microcontroller interface
- on the Tadpole Sparcbook 3.  This device handles power-management
- events, and can also notice the attachment/detachment of external
- monitors and mice.
-
 config BBC_I2C
tristate "UltraSPARC-III bootbus i2c controller driver"
depends on PCI && SPARC64
diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
index 44347c918f6b..9db2faabfae8 100644
--- a/drivers/sbus/char/Makefile
+++ b/drivers/sbus/char/Makefile
@@ -14,6 +14,5 @@ obj-$(CONFIG_ENVCTRL) += envctrl.o
 obj-$(CONFIG_DISPLAY7SEG)  += display7seg.o
 obj-$(CONFIG_OBP_FLASH)+= flash.o
 obj-$(CONFIG_SUN_OPENPROMIO)   += openprom.o
-obj-$(CONFIG_TADPOLE_TS102_UCTRL)  += uctrl.o
 obj-$(CONFIG_BBC_I2C)  += bbc.o
 obj-$(CONFIG_ORACLE_DAX)   += oradax.o
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
deleted file mode 100644
index 0660425e3a5a..
--- a/drivers/sbus/char/uctrl.c
+++ /dev/null
@@ -1,435 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
- *
- * Copyright 1999 Derrick J Brashear (sha...@dementia.org)
- * Copyright 2008 David S. Miller (da...@davemloft.net)
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-
-#define DEBUG 1
-#ifdef DEBUG
-#define dprintk(x) printk x
-#else
-#define dprintk(x)
-#endif
-
-struct uctrl_regs {
-   u32 uctrl_intr;
-   u32 uctrl_data;
-   u32 uctrl_stat;
-   u32 uctrl_xxx[5];
-};
-
-struct ts102_regs {
-   u32 card_a_intr;
-   u32 card_a_stat;
-   u32 card_a_ctrl;
-   u32 card_a_xxx;
-   u32 card_b_intr;
-   u32 card_b_stat;
-   u32 card_b_ctrl;
-   u32 card_b_xxx;
-   u32 uctrl_intr;
-   u32 uctrl_data;
-   u32 uctrl_stat;
-   u32 uctrl_xxx;
-   u32 ts102_xxx[4];
-};
-
-/* Bits for uctrl_intr register */
-#define UCTRL_INTR_TXE_REQ 0x01/* transmit FIFO empty int req */
-#define UCTRL_INTR_TXNF_REQ0x02/* transmit FIFO not full int req */
-#define UCTRL_INTR_RXNE_REQ0x04/* receive FIFO not empty int req */
-#define UCTRL_INTR_RXO_REQ 0x08/* receive FIFO overflow int req */
-#define UCTRL_INTR_TXE_MSK 0x10/* transmit FIFO empty mask */
-#define UCTRL_INTR_TXNF_MSK0x20/* transmit FIFO not full mask */
-#define UCTRL_INTR_RXNE_MSK0x40/* receive FIFO not empty mask */
-#define UCTRL_INTR_RXO_MSK 0x80/* receive FIFO overflow mask */
-
-/* Bits for uctrl_stat register */
-#define UCTRL_STAT_TXE_STA 0x01/* transmit FIFO empty status */
-#define UCTRL_STAT_TXNF_STA0x02/* transmit FIFO not full status */
-#define UCTRL_STAT_RXNE_STA0x04/* receive FIFO not empty status */
-#define UCTRL_STAT_RXO_STA 0x08/* receive FIFO overflow status */
-
-static DEFINE_MUTEX(uctrl_mutex);
-static const char *uctrl_extstatus[16] = {
-"main power available",
-"internal battery attached",
-"external battery attached",
-"external VGA attached",
-"external keyboard attached",
-"external mouse attached",
-"lid down",
-"internal battery currently charging",
-"external battery currently charging",
-"internal battery currently discharging",
-"external battery currently discharging",
-};
-
-/* Everything required for one transaction with the uctrl */
-struct uctrl_txn {
-   u8 opcode;
-   u8 inbits;
-   u8 outbits;
-   u8 *inbuf;
-   u8 *outbuf;
-};
-
-struct uctrl_status {
-   u8 current_temp; /* 0x07 */
-   u8 reset_status; /* 0x0b */
-   u16 event_status; /* 0x0c */
-   u16 error_status; /* 0x10 */
-   u16 external_status; /* 0x11, 0x1b */
-   u8 internal_charge; /* 0x18 */
-   u8 external_charge; /* 0x19 */

[PATCH 19/27] sparc32: Drop additional sun4d bits

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Drop sun4d specific support. Not used by LEON.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/io-unit.h |  59 
 arch/sparc/include/asm/obio.h| 226 ---
 arch/sparc/include/asm/sbi.h | 116 
 arch/sparc/kernel/entry.S|   1 -
 arch/sparc/kernel/ioport.c   |   1 -
 arch/sparc/mm/Makefile   |   2 +-
 arch/sparc/mm/io-unit.c  | 283 ---
 arch/sparc/mm/srmmu.c|   1 -
 8 files changed, 1 insertion(+), 688 deletions(-)

diff --git a/arch/sparc/include/asm/io-unit.h b/arch/sparc/include/asm/io-unit.h
deleted file mode 100644
index 8c38f5b9f927..
--- a/arch/sparc/include/asm/io-unit.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* io-unit.h: Definitions for the sun4d IO-UNIT.
- *
- * Copyright (C) 1997,1998 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
- */
-#ifndef _SPARC_IO_UNIT_H
-#define _SPARC_IO_UNIT_H
-
-#include 
-#include 
-#include 
-
-/* The io-unit handles all virtual to physical address translations
- * that occur between the SBUS and physical memory.  Access by
- * the cpu to IO registers and similar go over the xdbus so are
- * translated by the on chip SRMMU.  The io-unit and the srmmu do
- * not need to have the same translations at all, in fact most
- * of the time the translations they handle are a disjunct set.
- * Basically the io-unit handles all dvma sbus activity.
- */
- 
-/* AIEEE, unlike the nice sun4m, these monsters have 
-   fixed DMA range 64M */
- 
-#define IOUNIT_DMA_BASE0xfc00 /* TOP - 64M */
-#define IOUNIT_DMA_SIZE0x0400 /* 64M */
-/* We use last 1M for sparc_dvma_malloc */
-#define IOUNIT_DVMA_SIZE0x0010 /* 1M */
-
-/* The format of an iopte in the external page tables */
-#define IOUPTE_PAGE  0xff00 /* Physical page number (PA[35:12])
*/
-#define IOUPTE_CACHE 0x0080 /* Cached (in Viking/MXCC) 
*/
-/* XXX Jakub, find out how to program SBUS streaming cache on XDBUS/sun4d.
- * XXX Actually, all you should need to do is find out where the registers
- * XXX are and copy over the sparc64 implementation I wrote.  There may be
- * XXX some horrible hwbugs though, so be careful.  -DaveM
- */
-#define IOUPTE_STREAM0x0040 /* Translation can use streaming cache 
*/
-#define IOUPTE_INTRA0x0008 /* SBUS direct slot->slot transfer  
*/
-#define IOUPTE_WRITE 0x0004 /* Writeable   
*/
-#define IOUPTE_VALID 0x0002 /* IOPTE is valid  
*/
-#define IOUPTE_PARITY0x0001 /* Parity is checked during DVMA   
*/
-
-struct iounit_struct {
-   unsigned long   bmap[(IOUNIT_DMA_SIZE >> (PAGE_SHIFT + 3)) / 
sizeof(unsigned long)];
-   spinlock_t  lock;
-   iopte_t __iomem *page_table;
-   unsigned long   rotor[3];
-   unsigned long   limit[4];
-};
-
-#define IOUNIT_BMAP1_START 0x
-#define IOUNIT_BMAP1_END   (IOUNIT_DMA_SIZE >> (PAGE_SHIFT + 1))
-#define IOUNIT_BMAP2_START IOUNIT_BMAP1_END
-#define IOUNIT_BMAP2_END   IOUNIT_BMAP2_START + (IOUNIT_DMA_SIZE >> 
(PAGE_SHIFT + 2))
-#define IOUNIT_BMAPM_START IOUNIT_BMAP2_END
-#define IOUNIT_BMAPM_END   ((IOUNIT_DMA_SIZE - IOUNIT_DVMA_SIZE) >> 
PAGE_SHIFT)
-
-#endif /* !(_SPARC_IO_UNIT_H) */
diff --git a/arch/sparc/include/asm/obio.h b/arch/sparc/include/asm/obio.h
deleted file mode 100644
index 1b151f738b00..
--- a/arch/sparc/include/asm/obio.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * obio.h:  Some useful locations in 0xF PA obio space on sun4d.
- *
- * Copyright (C) 1997 Jakub Jelinek 
- */
-
-#ifndef _SPARC_OBIO_H
-#define _SPARC_OBIO_H
-
-#include 
-
-/* This weird monster likes to use the very upper parts of
-   36bit PA for these things :) */
-   
-/* CSR space (for each XDBUS)
- *  
- *  |   0xFE  |   DEVID|| XDBUS ID |   |
- *  
- *  35  28 2720 1910 98 7 0
- */
-   
-#define CSR_BASE_ADDR  0xe000
-#define CSR_CPU_SHIFT  (32 - 4 - 5)
-#define CSR_XDBUS_SHIFT8
-
-#define CSR_BASE(cpu) (((CSR_BASE_ADDR >> CSR_CPU_SHIFT) + cpu) << 
CSR_CPU_SHIFT)
-
-/* ECSR space (not for each XDBUS)
- *  
- *  |   0xF  | DEVID[7:1] |   |
- *  
- *  35 32 3125 240
- */
-   
-#define 

[PATCH 16/27] sparc32: Drop use of sparc_config

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

sparc_config were used to handle the differences between the machines.
With only LEON supported sparc_config is no longer required.

Refactor the time code a litte as some parts are obsolete and other
parts are only used when SMP is not enabled.

Signed-off-by: Sam Ravnborg 
Cc: Sam Ravnborg 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/include/asm/timer_32.h |  1 +
 arch/sparc/kernel/irq.h   | 37 +++---
 arch/sparc/kernel/irq_32.c|  3 --
 arch/sparc/kernel/leon_kernel.c   | 27 +++--
 arch/sparc/kernel/of_device_32.c  |  4 +--
 arch/sparc/kernel/time_32.c   | 64 +--
 6 files changed, 33 insertions(+), 103 deletions(-)

diff --git a/arch/sparc/include/asm/timer_32.h 
b/arch/sparc/include/asm/timer_32.h
index eecd2696922d..1cd89a99966f 100644
--- a/arch/sparc/include/asm/timer_32.h
+++ b/arch/sparc/include/asm/timer_32.h
@@ -17,6 +17,7 @@
 #include   /* For SUN4M_NCPUS */
 
 #define SBUS_CLOCK_RATE   200 /* 2MHz */
+#define LEON_CLOCK_RATE   100
 #define TIMER_VALUE_SHIFT 9
 #define TIMER_VALUE_MASK  0x3f
 #define TIMER_LIMIT_BIT   (1 << 31)  /* Bit 31 in Counter-Timer register */
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h
index 0d9b740725b4..8a0b314c8299 100644
--- a/arch/sparc/kernel/irq.h
+++ b/arch/sparc/kernel/irq.h
@@ -44,38 +44,6 @@ struct sun4m_irq_global {
 extern struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
 extern struct sun4m_irq_global __iomem *sun4m_irq_global;
 
-/* The following definitions describe the individual platform features: */
-#define FEAT_L10_CLOCKSOURCE (1 << 0) /* L10 timer is used as a clocksource */
-#define FEAT_L10_CLOCKEVENT  (1 << 1) /* L10 timer is used as a clockevent */
-#define FEAT_L14_ONESHOT (1 << 2) /* L14 timer clockevent can oneshot */
-
-/*
- * Platform specific configuration
- * The individual platforms assign their platform
- * specifics in their init functions.
- */
-struct sparc_config {
-   void (*init_timers)(void);
-   unsigned int (*build_device_irq)(struct platform_device *op,
-unsigned int real_irq);
-
-   /* generic clockevent features - see FEAT_* above */
-   int features;
-
-   /* clock rate used for clock event timer */
-   int clock_rate;
-
-   /* one period for clock source timer */
-   unsigned int cs_period;
-
-   /* function to obtain offsett for cs period */
-   unsigned int (*get_cycles_offset)(void);
-
-   void (*clear_clock_irq)(void);
-   void (*load_profile_irq)(int cpu, unsigned int limit);
-};
-extern struct sparc_config sparc_config;
-
 unsigned int irq_alloc(unsigned int real_irq, unsigned int pil);
 void irq_link(unsigned int irq);
 void irq_unlink(unsigned int irq);
@@ -89,6 +57,11 @@ void sun4m_nmi(struct pt_regs *regs);
 /* sun4d_irq.c */
 void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs);
 
+/* leon_kernel.c */
+void leon_clear_clock_irq(void);
+void leon_load_profile_irq(int cpu, unsigned int limit);
+u32 leon_cycles_offset(void);
+
 #ifdef CONFIG_SMP
 
 /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index a6af08fce796..f76f57073323 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -24,9 +24,6 @@
 #include "kernel.h"
 #include "irq.h"
 
-/* platform specific irq setup */
-struct sparc_config sparc_config;
-
 unsigned long arch_local_irq_save(void)
 {
unsigned long retval;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index ea04bad6a118..fa9cdaffdc6b 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -237,12 +237,6 @@ unsigned int leon_build_device_irq(unsigned int real_irq,
return irq;
 }
 
-static unsigned int _leon_build_device_irq(struct platform_device *op,
-  unsigned int real_irq)
-{
-   return leon_build_device_irq(real_irq, handle_simple_irq, "edge", 0);
-}
-
 void leon_update_virq_handling(unsigned int virq,
  irq_flow_handler_t flow_handler,
  const char *name, int do_ack)
@@ -258,7 +252,7 @@ void leon_update_virq_handling(unsigned int virq,
irq_set_chip_data(virq, (void *)mask);
 }
 
-static u32 leon_cycles_offset(void)
+u32 leon_cycles_offset(void)
 {
u32 rld, val, ctrl, off;
 
@@ -312,14 +306,6 @@ void __init leon_init_timers(void)
u32 config;
u32 ctrl;
 
-   sparc_config.get_cycles_offset = leon_cycles_offset;
-   sparc_config.cs_period = 100 / HZ;
-   sparc_config.features |= FEAT_L10_CLOCKSOURCE;
-
-#ifndef CONFIG_SMP
-   sparc_config.features |= FEAT_L10_CLOCKEVENT;
-#endif
-
leondebug_irq_disable = 0;
leon_debug_irqout = 0;
master_l10_counter = (u32 __iomem 

[PATCH 08/27] sparc32: Drop patching of interrupt vector

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Drop the sun4m specific handling and the patching that
takes place in sun4d and LEON.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/kernel/entry.S   | 98 -
 arch/sparc/kernel/kernel.h  |  1 -
 arch/sparc/kernel/leon_kernel.c | 16 ---
 arch/sparc/kernel/sun4d_irq.c   | 25 ---
 4 files changed, 140 deletions(-)

diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 7cf148a996b9..9bd3813b872d 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -79,15 +79,6 @@ bad_trap_handler:
 real_irq_entry:
SAVE_ALL
 
-#ifdef CONFIG_SMP
-   .globl  patchme_maybe_smp_msg
-
-   cmp %l7, 11
-patchme_maybe_smp_msg:
-   bgu maybe_smp4m_msg
-nop
-#endif
-
 real_irq_continue:
or  %l0, PSR_PIL, %g2
wr  %g2, 0x0, %psr
@@ -105,95 +96,6 @@ patch_handler_irq:
RESTORE_ALL
 
 #ifdef CONFIG_SMP
-   /* SMP per-cpu ticker interrupts are handled specially. */
-smp4m_ticker:
-   bne real_irq_continue+4
-or %l0, PSR_PIL, %g2
-   wr  %g2, 0x0, %psr
-   WRITE_PAUSE
-   wr  %g2, PSR_ET, %psr
-   WRITE_PAUSE
-   callsmp4m_percpu_timer_interrupt
-add%sp, STACKFRAME_SZ, %o0
-   wr  %l0, PSR_ET, %psr
-   WRITE_PAUSE
-   RESTORE_ALL
-
-#define GET_PROCESSOR4M_ID(reg)\
-   rd  %tbr, %reg; \
-   srl %reg, 12, %reg; \
-   and %reg, 3, %reg;
-
-   /* Here is where we check for possible SMP IPI passed to us
-* on some level other than 15 which is the NMI and only used
-* for cross calls.  That has a separate entry point below.
-*
-* IPIs are sent on Level 12, 13 and 14. See IRQ_IPI_*.
-*/
-maybe_smp4m_msg:
-   GET_PROCESSOR4M_ID(o3)
-   sethi   %hi(sun4m_irq_percpu), %l5
-   sll %o3, 2, %o3
-   or  %l5, %lo(sun4m_irq_percpu), %o5
-   sethi   %hi(0x7000), %o2! Check all soft-IRQs
-   ld  [%o5 + %o3], %o1
-   ld  [%o1 + 0x00], %o3   ! sun4m_irq_percpu[cpu]->pending
-   andcc   %o3, %o2, %g0
-   be,asmp4m_ticker
-cmp%l7, 14
-   /* Soft-IRQ IPI */
-   st  %o2, [%o1 + 0x04]   ! 
sun4m_irq_percpu[cpu]->clear=0x7000
-   WRITE_PAUSE
-   ld  [%o1 + 0x00], %g0   ! sun4m_irq_percpu[cpu]->pending
-   WRITE_PAUSE
-   or  %l0, PSR_PIL, %l4
-   wr  %l4, 0x0, %psr
-   WRITE_PAUSE
-   wr  %l4, PSR_ET, %psr
-   WRITE_PAUSE
-   srl %o3, 28, %o2! shift for simpler checks below
-maybe_smp4m_msg_check_single:
-   andcc   %o2, 0x1, %g0
-   beq,a   maybe_smp4m_msg_check_mask
-andcc  %o2, 0x2, %g0
-   callsmp_call_function_single_interrupt
-nop
-   andcc   %o2, 0x2, %g0
-maybe_smp4m_msg_check_mask:
-   beq,a   maybe_smp4m_msg_check_resched
-andcc  %o2, 0x4, %g0
-   callsmp_call_function_interrupt
-nop
-   andcc   %o2, 0x4, %g0
-maybe_smp4m_msg_check_resched:
-   /* rescheduling is done in RESTORE_ALL regardless, but incr stats */
-   beq,a   maybe_smp4m_msg_out
-nop
-   callsmp_resched_interrupt
-nop
-maybe_smp4m_msg_out:
-   RESTORE_ALL
-
-
-   .globl  smp4d_ticker
-   /* SMP per-cpu ticker interrupts are handled specially. */
-smp4d_ticker:
-   SAVE_ALL
-   or  %l0, PSR_PIL, %g2
-   sethi   %hi(CC_ICLR), %o0
-   sethi   %hi(1 << 14), %o1
-   or  %o0, %lo(CC_ICLR), %o0
-   stha%o1, [%o0] ASI_M_MXCC   /* Clear PIL 14 in MXCC's ICLR */
-   wr  %g2, 0x0, %psr
-   WRITE_PAUSE
-   wr  %g2, PSR_ET, %psr
-   WRITE_PAUSE
-   callsmp4d_percpu_timer_interrupt
-add%sp, STACKFRAME_SZ, %o0
-   wr  %l0, PSR_ET, %psr
-   WRITE_PAUSE
-   RESTORE_ALL
-
.globl  smpleon_ipi
.extern leon_ipi_interrupt
/* SMP per-cpu IPI interrupts are handled specially. */
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 1d3980ac0658..85a3c3d1195e 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -145,7 +145,6 @@ extern char cputypval[];
 extern unsigned long lvl14_save[4];
 extern unsigned int real_irq_entry[];
 extern unsigned int smp4d_ticker[];
-extern unsigned int patchme_maybe_smp_msg[];
 
 /* trampoline_32.S */
 extern unsigned long sun4m_cpu_startup;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 4c61da491fee..ea04bad6a118 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -421,22 +421,6 @@ void __init leon_init_timers(void)
if (eirq != 0)
leon_eirq_setup(eirq);
 
-#ifdef CONFIG_SMP
-   {
-   unsigned long flags;
-
-   /*
- 

[PATCH 02/27] sparc32: Drop sun4m/sun4d support from head_32.S

2023-12-19 Thread Sam Ravnborg via B4 Relay
From: Sam Ravnborg 

Remove the most obvious parts of sun4* support from head_32.S.
Use a single print if a sun4* machine is detected thus restricting
boots to LEON machines.

Signed-off-by: Sam Ravnborg 
Cc: "David S. Miller" 
Cc: Arnd Bergmann 
Cc: Andreas Larsson 
---
 arch/sparc/kernel/head_32.S | 190 +++-
 1 file changed, 9 insertions(+), 181 deletions(-)

diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index 964c61b5cd03..03dc232dd235 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -45,11 +45,7 @@ cputypvar:
.align 4
 
 notsup:
-   .asciz  "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n"
-   .align 4
-
-sun4e_notsup:
-.asciz  "Sparc-Linux sun4e support does not exist\n\n"
+   .asciz  "This kernel only supports LEON SPARC V8\n\n"
.align 4
 
 /* The trap-table - located in the __HEAD section */
@@ -215,114 +211,10 @@ not_a_sun4:
be  leon_remap  /* It is a LEON - jump */
 nop
 
-   /* Sanity-check, is MMU enabled */
-   lda [%g0] ASI_M_MMUREGS, %g1
-   andcc   %g1, 1, %g0
-   be  halt_notsup
-nop
-
-   /* Check for a viking (TI) module. */
-   cmp %g3, PSR_IMPL_TI
-   bne srmmu_not_viking
-nop
-
-   /* Figure out what kind of viking we are on.
-* We need to know if we have to play with the
-* AC bit and disable traps or not.
-*/
-
-   /* I've only seen MicroSparc's on SparcClassics with this
-* bit set.
-*/
-   set 0x800, %g2
-   lda [%g0] ASI_M_MMUREGS, %g3! peek in the control 
reg
-   and %g2, %g3, %g3
-   subcc   %g3, 0x0, %g0
-   bnz srmmu_not_viking! is in mbus 
mode
-nop
-
-   rd  %psr, %g3   ! DO NOT TOUCH %g3
-   andn%g3, PSR_ET, %g2
-   wr  %g2, 0x0, %psr
-   WRITE_PAUSE
-
-   /* Get context table pointer, then convert to
-* a physical address, which is 36 bits.
-*/
-   set AC_M_CTPR, %g4
-   lda [%g4] ASI_M_MMUREGS, %g4
-   sll %g4, 0x4, %g4   ! We use this below
-   ! DO NOT TOUCH %g4
-
-   /* Set the AC bit in the Viking's MMU control reg. */
-   lda [%g0] ASI_M_MMUREGS, %g5! DO NOT TOUCH %g5
-   set 0x8000, %g6 ! AC bit mask
-   or  %g5, %g6, %g6   ! Or it in...
-   sta %g6, [%g0] ASI_M_MMUREGS! Close your eyes...
-
-   /* Grrr, why does it seem like every other load/store
-* on the sun4m is in some ASI space...
-* Fine with me, let's get the pointer to the level 1
-* page table directory and fetch its entry.
-*/
-   lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr
-   srl %o1, 0x4, %o1   ! Clear low 4 bits
-   sll %o1, 0x8, %o1   ! Make physical
-
-   /* Ok, pull in the PTD. */
-   lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB 
pgd
-
-   /* Calculate to KERNBASE entry. */
-   add %o1, KERNBASE >> (PGDIR_SHIFT - 2), %o3
-
-   /* Poke the entry into the calculated address. */
-   sta %o2, [%o3] ASI_M_BYPASS
-
-   /* I don't get it Sun, if you engineered all these
-* boot loaders and the PROM (thank you for the debugging
-* features btw) why did you not have them load kernel
-* images up in high address space, since this is necessary
-* for ABI compliance anyways?  Does this low-mapping provide
-* enhanced interoperability?
-*
-* "The PROM is the computer."
-*/
-
-   /* Ok, restore the MMU control register we saved in %g5 */
-   sta %g5, [%g0] ASI_M_MMUREGS! POW... ouch
-
-   /* Turn traps back on.  We saved it in %g3 earlier. */
-   wr  %g3, 0x0, %psr  ! tick tock, tick tock
-
-   /* Now we burn precious CPU cycles due to bad engineering. */
-   WRITE_PAUSE
-
-   /* Wow, all that just to move a 32-bit value from one
-* place to another...  Jump to high memory.
-*/
-   b   go_to_highmem
+   /* Not LEON - halt */
+   

[PATCH v3 4/6] input/vmmouse: Use vmware_hypercall API

2023-12-19 Thread Alexey Makhalov
From: Alexey Makhalov 

Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code. No functional changes intended.

Signed-off-by: Alexey Makhalov 
Reviewed-by: Nadav Amit 
Reviewed-by: Zack Rusin 
Acked-by: Dmitry Torokhov 
---
 drivers/input/mouse/vmmouse.c | 76 ++-
 1 file changed, 22 insertions(+), 54 deletions(-)

diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c
index ea9eff7c8099..fb1d986a6895 100644
--- a/drivers/input/mouse/vmmouse.c
+++ b/drivers/input/mouse/vmmouse.c
@@ -21,19 +21,16 @@
 #include "psmouse.h"
 #include "vmmouse.h"
 
-#define VMMOUSE_PROTO_MAGIC0x564D5868U
-
 /*
  * Main commands supported by the vmmouse hypervisor port.
  */
-#define VMMOUSE_PROTO_CMD_GETVERSION   10
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA  39
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS40
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND   41
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT   86
+#define VMWARE_CMD_ABSPOINTER_DATA 39
+#define VMWARE_CMD_ABSPOINTER_STATUS   40
+#define VMWARE_CMD_ABSPOINTER_COMMAND  41
+#define VMWARE_CMD_ABSPOINTER_RESTRICT 86
 
 /*
- * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND
+ * Subcommands for VMWARE_CMD_ABSPOINTER_COMMAND
  */
 #define VMMOUSE_CMD_ENABLE 0x45414552U
 #define VMMOUSE_CMD_DISABLE0x00f5U
@@ -76,28 +73,6 @@ struct vmmouse_data {
char dev_name[128];
 };
 
-/*
- * Hypervisor-specific bi-directional communication channel
- * implementing the vmmouse protocol. Should never execute on
- * bare metal hardware.
- */
-#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4)  \
-({ \
-   unsigned long __dummy1, __dummy2;   \
-   __asm__ __volatile__ (VMWARE_HYPERCALL :\
-   "=a"(out1), \
-   "=b"(out2), \
-   "=c"(out3), \
-   "=d"(out4), \
-   "=S"(__dummy1), \
-   "=D"(__dummy2) :\
-   "a"(VMMOUSE_PROTO_MAGIC),   \
-   "b"(in1),   \
-   "c"(VMMOUSE_PROTO_CMD_##cmd),   \
-   "d"(0) :\
-   "memory");  \
-})
-
 /**
  * vmmouse_report_button - report button state on the correct input device
  *
@@ -145,14 +120,12 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse 
*psmouse)
struct input_dev *abs_dev = priv->abs_dev;
struct input_dev *pref_dev;
u32 status, x, y, z;
-   u32 dummy1, dummy2, dummy3;
unsigned int queue_length;
unsigned int count = 255;
 
while (count--) {
/* See if we have motion data. */
-   VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
-   status, dummy1, dummy2, dummy3);
+   status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) {
psmouse_err(psmouse, "failed to fetch status data\n");
/*
@@ -172,7 +145,8 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse 
*psmouse)
}
 
/* Now get it */
-   VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z);
+   status = vmware_hypercall4(VMWARE_CMD_ABSPOINTER_DATA, 4,
+  , , );
 
/*
 * And report what we've got. Prefer to report button
@@ -247,14 +221,10 @@ static psmouse_ret_t vmmouse_process_byte(struct psmouse 
*psmouse)
 static void vmmouse_disable(struct psmouse *psmouse)
 {
u32 status;
-   u32 dummy1, dummy2, dummy3, dummy4;
-
-   VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE,
-   dummy1, dummy2, dummy3, dummy4);
 
-   VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
-   status, dummy1, dummy2, dummy3);
+   vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE);
 
+   status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR)
psmouse_warn(psmouse, "failed to disable vmmouse device\n");
 }
@@ -271,26 +241,24 @@ static void vmmouse_disable(struct psmouse *psmouse)
 static int vmmouse_enable(struct psmouse *psmouse)
 {
u32 status, version;
-   u32 dummy1, dummy2, dummy3, dummy4;
 
/*
 * Try enabling the device. If successful, we should be able to
 * read valid version ID back from it.
 */
-   VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE,
-   dummy1, dummy2, dummy3, dummy4);
+   

[PATCH v3 6/6] x86/vmware: Add TDX hypercall support

2023-12-19 Thread Alexey Makhalov
From: Alexey Makhalov 

VMware hypercalls use I/O port, VMCALL or VMMCALL instructions.
Add __tdx_hypercall path to support TDX guests.

No change in high bandwidth hypercalls, as only low bandwidth
ones are supported for TDX guests.

Co-developed-by: Tim Merrifield 
Signed-off-by: Tim Merrifield 
Signed-off-by: Alexey Makhalov 
Reviewed-by: Nadav Amit 
---
 arch/x86/include/asm/vmware.h | 83 +++
 arch/x86/kernel/cpu/vmware.c  | 24 ++
 2 files changed, 107 insertions(+)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 719e41260ece..cad6f5b371a8 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -34,12 +34,65 @@
 #define VMWARE_CMD_GETHZ   45
 #define VMWARE_CMD_GETVCPU_INFO68
 #define VMWARE_CMD_STEALCLOCK  91
+/*
+ * Hypercall command mask:
+ *   bits[6:0] command, range [0, 127]
+ *   bits[19:16] sub-command, range [0, 15]
+ */
+#define VMWARE_CMD_MASK0xf007fU
 
 #define CPUID_VMWARE_FEATURES_ECX_VMMCALL  BIT(0)
 #define CPUID_VMWARE_FEATURES_ECX_VMCALL   BIT(1)
 
 extern u8 vmware_hypercall_mode;
 
+#define VMWARE_TDX_VENDOR_LEAF 0x1af7e4909ULL
+#define VMWARE_TDX_HCALL_FUNC  1
+
+extern unsigned long vmware_tdx_hypercall(unsigned long cmd,
+ struct tdx_module_args *args);
+
+/*
+ * TDCALL[TDG.VP.VMCALL] uses rax (arg0) and rcx (arg2), while the use of
+ * rbp (arg6) is discouraged by the TDX specification. Therefore, we
+ * remap those registers to r12, r13 and r14, respectively.
+ */
+static inline
+unsigned long vmware_tdx_hypercall_args(unsigned long cmd, unsigned long in1,
+   unsigned long in3, unsigned long in4,
+   unsigned long in5, unsigned long in6,
+   uint32_t *out1, uint32_t *out2,
+   uint32_t *out3, uint32_t *out4,
+   uint32_t *out5, uint32_t *out6)
+{
+   unsigned long ret;
+
+   struct tdx_module_args args = {
+   .rbx = in1,
+   .rdx = in3,
+   .rsi = in4,
+   .rdi = in5,
+   .r14 = in6,
+   };
+
+   ret = vmware_tdx_hypercall(cmd, );
+
+   if (out1)
+   *out1 = args.rbx;
+   if (out2)
+   *out2 = args.r13;
+   if (out3)
+   *out3 = args.rdx;
+   if (out4)
+   *out4 = args.rsi;
+   if (out5)
+   *out5 = args.rdi;
+   if (out6)
+   *out6 = args.r14;
+
+   return ret;
+}
+
 /*
  * The low bandwidth call. The low word of edx is presumed to have OUT bit
  * set. The high word of edx may contain input data from the caller.
@@ -67,6 +120,11 @@ unsigned long vmware_hypercall1(unsigned long cmd, unsigned 
long in1)
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall_args(cmd, in1, 0, 0, 0, 0,
+NULL, NULL, NULL,
+NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -85,6 +143,11 @@ unsigned long vmware_hypercall3(unsigned long cmd, unsigned 
long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall_args(cmd, in1, 0, 0, 0, 0,
+out1, out2, NULL,
+NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=b" (*out1), "=c" (*out2)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -104,6 +167,11 @@ unsigned long vmware_hypercall4(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall_args(cmd, in1, 0, 0, 0, 0,
+out1, out2, out3,
+NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -123,6 +191,11 @@ unsigned long vmware_hypercall5(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall_args(cmd, in1, in3, in4, in5, 0,
+NULL, out2, NULL,
+NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=c" (*out2)
: [port] "i" 

[PATCH v3 2/6] x86/vmware: Introduce vmware_hypercall API

2023-12-19 Thread Alexey Makhalov
From: Alexey Makhalov 

Introduce vmware_hypercall family of functions. It is a common
implementation to be used by the VMware guest code and virtual
device drivers in architecture independent manner.

The API consists of vmware_hypercallX and vmware_hypercall_hb_{out,in}
set of functions by analogy with KVM hypercall API. Architecture
specific implementation is hidden inside.

It will simplify future enhancements in VMware hypercalls such
as SEV-ES and TDX related changes without needs to modify a
caller in device drivers code.

Current implementation extends an idea from commit bac7b4e84323
("x86/vmware: Update platform detection code for VMCALL/VMMCALL
hypercalls") to have a slow, but safe path in VMWARE_HYPERCALL
earlier during the boot when alternatives are not yet applied.
This logic was inherited from VMWARE_CMD from the commit mentioned
above. Default alternative code was optimized by size to reduce
excessive nop alignment once alternatives are applied. Total
default code size is 26 bytes, in worse case (3 bytes alternative)
remaining 23 bytes will be aligned by only 3 long NOP instructions.

Signed-off-by: Alexey Makhalov 
Reviewed-by: Nadav Amit 
Reviewed-by: Jeff Sipek 
---
 arch/x86/include/asm/vmware.h | 262 ++
 arch/x86/kernel/cpu/vmware.c  |  35 ++---
 2 files changed, 220 insertions(+), 77 deletions(-)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 3636faa8b4fe..719e41260ece 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -40,69 +40,219 @@
 
 extern u8 vmware_hypercall_mode;
 
-/* The low bandwidth call. The low word of edx is presumed clear. */
-#define VMWARE_HYPERCALL   \
-   ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \
- "inl (%%dx), %%eax",  \
- "vmcall", X86_FEATURE_VMCALL, \
- "vmmcall", X86_FEATURE_VMW_VMMCALL)
-
 /*
- * The high bandwidth out call. The low word of edx is presumed to have the
- * HB and OUT bits set.
+ * The low bandwidth call. The low word of edx is presumed to have OUT bit
+ * set. The high word of edx may contain input data from the caller.
  */
-#define VMWARE_HYPERCALL_HB_OUT
\
-   ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; 
" \
- "rep outsb",  \
+#define VMWARE_HYPERCALL   \
+   ALTERNATIVE_3("cmpb $"  \
+   __stringify(CPUID_VMWARE_FEATURES_ECX_VMMCALL)  \
+   ", %[mode]\n\t" \
+ "jg 2f\n\t"   \
+ "je 1f\n\t"   \
+ "movw %[port], %%dx\n\t"  \
+ "inl (%%dx), %%eax\n\t"   \
+ "jmp 3f\n\t"  \
+ "1: vmmcall\n\t"  \
+ "jmp 3f\n\t"  \
+ "2: vmcall\n\t"   \
+ "3:\n\t", \
+ "movw %[port], %%dx\n\t"  \
+ "inl (%%dx), %%eax", X86_FEATURE_HYPERVISOR,  \
  "vmcall", X86_FEATURE_VMCALL, \
  "vmmcall", X86_FEATURE_VMW_VMMCALL)
 
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
+{
+   unsigned long out0;
+
+   asm_inline volatile (VMWARE_HYPERCALL
+   : "=a" (out0)
+   : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+   : "cc", "memory");
+   return out0;
+}
+
+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2)
+{
+   unsigned long out0;
+
+   asm_inline volatile (VMWARE_HYPERCALL
+   : "=a" (out0), "=b" (*out1), "=c" (*out2)
+   : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+   : "cc", "memory");
+   return out0;
+}
+
+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+   

[PATCH v3 3/6] ptp/vmware: Use vmware_hypercall API

2023-12-19 Thread Alexey Makhalov
From: Alexey Makhalov 

Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code. No functional changes intended.

Signed-off-by: Alexey Makhalov 
Reviewed-by: Nadav Amit 
Reviewed-by: Jeff Sipek 
---
 drivers/ptp/ptp_vmw.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/ptp/ptp_vmw.c b/drivers/ptp/ptp_vmw.c
index 27c5547aa8a9..e5bb521b9b82 100644
--- a/drivers/ptp/ptp_vmw.c
+++ b/drivers/ptp/ptp_vmw.c
@@ -14,7 +14,6 @@
 #include 
 #include 
 
-#define VMWARE_MAGIC 0x564D5868
 #define VMWARE_CMD_PCLK(nr) ((nr << 16) | 97)
 #define VMWARE_CMD_PCLK_GETTIME VMWARE_CMD_PCLK(0)
 
@@ -24,15 +23,10 @@ static struct ptp_clock *ptp_vmw_clock;
 
 static int ptp_vmw_pclk_read(u64 *ns)
 {
-   u32 ret, nsec_hi, nsec_lo, unused1, unused2, unused3;
-
-   asm volatile (VMWARE_HYPERCALL :
-   "=a"(ret), "=b"(nsec_hi), "=c"(nsec_lo), "=d"(unused1),
-   "=S"(unused2), "=D"(unused3) :
-   "a"(VMWARE_MAGIC), "b"(0),
-   "c"(VMWARE_CMD_PCLK_GETTIME), "d"(0) :
-   "memory");
+   u32 ret, nsec_hi, nsec_lo;
 
+   ret = vmware_hypercall3(VMWARE_CMD_PCLK_GETTIME, 0,
+   _hi, _lo);
if (ret == 0)
*ns = ((u64)nsec_hi << 32) | nsec_lo;
return ret;
-- 
2.39.0



[PATCH v3 5/6] drm/vmwgfx: Use vmware_hypercall API

2023-12-19 Thread Alexey Makhalov
From: Alexey Makhalov 

Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code.

drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h: implement arm64 variant
of vmware_hypercall. And keep it here until introduction of ARM64
VMWare hypervisor interface.

Signed-off-by: Alexey Makhalov 
Reviewed-by: Nadav Amit 
Reviewed-by: Zack Rusin 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c   | 173 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 +++---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h   | 185 
 3 files changed, 197 insertions(+), 358 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 2651fe0ef518..1f15990d3934 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -48,8 +48,6 @@
 
 #define RETRIES 3
 
-#define VMW_HYPERVISOR_MAGIC0x564D5868
-
 #define VMW_PORT_CMD_MSG30
 #define VMW_PORT_CMD_HB_MSG 0
 #define VMW_PORT_CMD_OPEN_CHANNEL  (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG)
@@ -104,20 +102,18 @@ static const char* const 
mksstat_kern_name_desc[MKSSTAT_KERN_COUNT][2] =
  */
 static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
 {
-   unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
+   u32 ecx, edx, esi, edi;
 
-   VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL,
-   (protocol | GUESTMSG_FLAG_COOKIE), si, di,
-   0,
-   VMW_HYPERVISOR_MAGIC,
-   eax, ebx, ecx, edx, si, di);
+   vmware_hypercall6(VMW_PORT_CMD_OPEN_CHANNEL,
+ (protocol | GUESTMSG_FLAG_COOKIE), 0,
+ , , , );
 
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
return -EINVAL;
 
channel->channel_id  = HIGH_WORD(edx);
-   channel->cookie_high = si;
-   channel->cookie_low  = di;
+   channel->cookie_high = esi;
+   channel->cookie_low  = edi;
 
return 0;
 }
@@ -133,17 +129,13 @@ static int vmw_open_channel(struct rpc_channel *channel, 
unsigned int protocol)
  */
 static int vmw_close_channel(struct rpc_channel *channel)
 {
-   unsigned long eax, ebx, ecx, edx, si, di;
-
-   /* Set up additional parameters */
-   si  = channel->cookie_high;
-   di  = channel->cookie_low;
+   u32 ecx;
 
-   VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL,
-   0, si, di,
-   channel->channel_id << 16,
-   VMW_HYPERVISOR_MAGIC,
-   eax, ebx, ecx, edx, si, di);
+   vmware_hypercall5(VMW_PORT_CMD_CLOSE_CHANNEL,
+ 0, channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ );
 
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
return -EINVAL;
@@ -163,24 +155,18 @@ static int vmw_close_channel(struct rpc_channel *channel)
 static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
 const char *msg, bool hb)
 {
-   unsigned long si, di, eax, ebx, ecx, edx;
+   u32 ebx, ecx;
unsigned long msg_len = strlen(msg);
 
/* HB port can't access encrypted memory. */
if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
-   unsigned long bp = channel->cookie_high;
-   u32 channel_id = (channel->channel_id << 16);
-
-   si = (uintptr_t) msg;
-   di = channel->cookie_low;
-
-   VMW_PORT_HB_OUT(
+   vmware_hypercall_hb_out(
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
-   msg_len, si, di,
-   VMWARE_HYPERVISOR_HB | channel_id |
-   VMWARE_HYPERVISOR_OUT,
-   VMW_HYPERVISOR_MAGIC, bp,
-   eax, ebx, ecx, edx, si, di);
+   msg_len,
+   channel->channel_id << 16,
+   (uintptr_t) msg, channel->cookie_low,
+   channel->cookie_high,
+   );
 
return ebx;
}
@@ -194,14 +180,13 @@ static unsigned long vmw_port_hb_out(struct rpc_channel 
*channel,
memcpy(, msg, bytes);
msg_len -= bytes;
msg += bytes;
-   si = channel->cookie_high;
-   di = channel->cookie_low;
-
-   VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16),
-word, si, di,
-channel->channel_id << 16,
-VMW_HYPERVISOR_MAGIC,
-eax, ebx, ecx, edx, si, di);
+
+   vmware_hypercall5(VMW_PORT_CMD_MSG |
+ (MSG_TYPE_SENDPAYLOAD << 16),
+ word, channel->channel_id << 16,
+ 

[PATCH v3 1/6] x86/vmware: Move common macros to vmware.h

2023-12-19 Thread Alexey Makhalov
From: Alexey Makhalov 

Move VMware hypercall macros to vmware.h. This is a prerequisite for
the introduction of vmware_hypercall API. No functional changes besides
exporting vmware_hypercall_mode symbol.

Signed-off-by: Alexey Makhalov 
Reviewed-by: Nadav Amit 
---
 arch/x86/include/asm/vmware.h | 69 ++-
 arch/x86/kernel/cpu/vmware.c  | 57 +++--
 2 files changed, 66 insertions(+), 60 deletions(-)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index ac9fc51e2b18..3636faa8b4fe 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -8,25 +8,37 @@
 
 /*
  * The hypercall definitions differ in the low word of the %edx argument
- * in the following way: the old port base interface uses the port
- * number to distinguish between high- and low bandwidth versions.
+ * in the following way: the old I/O port based interface uses the port
+ * number to distinguish between high- and low bandwidth versions, and
+ * uses IN/OUT instructions to define transfer direction.
  *
  * The new vmcall interface instead uses a set of flags to select
  * bandwidth mode and transfer direction. The flags should be loaded
  * into %dx by any user and are automatically replaced by the port
- * number if the VMWARE_HYPERVISOR_PORT method is used.
+ * number if the I/O port method is used.
  *
  * In short, new driver code should strictly use the new definition of
  * %dx content.
  */
 
-/* Old port-based version */
-#define VMWARE_HYPERVISOR_PORT0x5658
-#define VMWARE_HYPERVISOR_PORT_HB 0x5659
+#define VMWARE_HYPERVISOR_HB   BIT(0)
+#define VMWARE_HYPERVISOR_OUT  BIT(1)
 
-/* Current vmcall / vmmcall version */
-#define VMWARE_HYPERVISOR_HB   BIT(0)
-#define VMWARE_HYPERVISOR_OUT  BIT(1)
+#define VMWARE_HYPERVISOR_PORT 0x5658
+#define VMWARE_HYPERVISOR_PORT_HB  (VMWARE_HYPERVISOR_PORT | \
+VMWARE_HYPERVISOR_HB)
+
+#define VMWARE_HYPERVISOR_MAGIC0x564d5868U
+
+#define VMWARE_CMD_GETVERSION  10
+#define VMWARE_CMD_GETHZ   45
+#define VMWARE_CMD_GETVCPU_INFO68
+#define VMWARE_CMD_STEALCLOCK  91
+
+#define CPUID_VMWARE_FEATURES_ECX_VMMCALL  BIT(0)
+#define CPUID_VMWARE_FEATURES_ECX_VMCALL   BIT(1)
+
+extern u8 vmware_hypercall_mode;
 
 /* The low bandwidth call. The low word of edx is presumed clear. */
 #define VMWARE_HYPERCALL   \
@@ -54,4 +66,43 @@
  "rep insb",   \
  "vmcall", X86_FEATURE_VMCALL, \
  "vmmcall", X86_FEATURE_VMW_VMMCALL)
+
+#define VMWARE_PORT(cmd, eax, ebx, ecx, edx)   \
+   __asm__("inl (%%dx), %%eax" :   \
+   "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\
+   "a"(VMWARE_HYPERVISOR_MAGIC),   \
+   "c"(VMWARE_CMD_##cmd),  \
+   "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) :\
+   "memory")
+
+#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx) \
+   __asm__("vmcall" :  \
+   "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\
+   "a"(VMWARE_HYPERVISOR_MAGIC),   \
+   "c"(VMWARE_CMD_##cmd),  \
+   "d"(0), "b"(UINT_MAX) : \
+   "memory")
+
+#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx)
\
+   __asm__("vmmcall" : \
+   "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\
+   "a"(VMWARE_HYPERVISOR_MAGIC),   \
+   "c"(VMWARE_CMD_##cmd),  \
+   "d"(0), "b"(UINT_MAX) : \
+   "memory")
+
+#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do {   \
+   switch (vmware_hypercall_mode) {\
+   case CPUID_VMWARE_FEATURES_ECX_VMCALL:  \
+   VMWARE_VMCALL(cmd, eax, ebx, ecx, edx); \
+   break;  \
+   case CPUID_VMWARE_FEATURES_ECX_VMMCALL: \
+   VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx);\
+   break;  \
+   default:\
+   VMWARE_PORT(cmd, eax, ebx, ecx, edx);   \
+   break;  \
+   }   \
+   } while 

[PATCH v3 0/6] VMware hypercalls enhancements

2023-12-19 Thread Alexey Makhalov
VMware hypercalls invocations were all spread out across the kernel
implementing same ABI as in-place asm-inline. With encrypted memory
and confidential computing it became harder to maintain every changes
in these hypercall implementations.

Intention of this patchset is to introduce arch independent VMware
hypercall API layer other subsystems such as device drivers can call
to, while hiding architecture specific implementation behind.

Second patch introduces the vmware_hypercall low and high bandwidth
families of functions, with little enhancements there.
Sixth patch adds tdx hypercall support

arm64 implementation of vmware_hypercalls is in drivers/gpu/drm/
vmwgfx/vmwgfx_msg_arm64.h and going to be moved to arch/arm64 with
a separate patchset with the introduction of VMware Linux guest
support for arm64.

No functional changes in drivers/input/mouse/vmmouse.c and
drivers/ptp/ptp_vmw.c

v2->v3 changes: (no functional changes in patches 1-5)
- Improved commit message in patches 1, 2 and 5 as was suggested by
  Borislav Petkov.
- To address Dave Hansen's concern, patch 6 was reorganized to avoid
  exporting bare __tdx_hypercall and to make exported vmware_tdx_hypercall
  VMWare guest specific.

v1->v2 changes (no functional changes):
- Improved commit message in patches 2 and 5.
- Added Reviewed-by for all patches.
- Added Ack from Dmitry Torokhov in patch 4. No fixes regarding reported
  by Simon Horman gcc error in this patch.

Alexey Makhalov (6):
  x86/vmware: Move common macros to vmware.h
  x86/vmware: Introduce vmware_hypercall API
  ptp/vmware: Use vmware_hypercall API
  input/vmmouse: Use vmware_hypercall API
  drm/vmwgfx: Use vmware_hypercall API
  x86/vmware: Add TDX hypercall support

 arch/x86/include/asm/vmware.h | 338 --
 arch/x86/kernel/cpu/vmware.c  | 116 +++-
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c   | 173 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 +
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h   | 185 
 drivers/input/mouse/vmmouse.c |  76 ++---
 drivers/ptp/ptp_vmw.c |  12 +-
 7 files changed, 577 insertions(+), 520 deletions(-)

-- 
2.39.0



Re: [PATCH] drivers: video: logo: use %u format specifier for unsigned int values

2023-12-19 Thread Randy Dunlap



On 12/19/23 07:14, Colin Ian King wrote:
> Currently the %d format specifier is being used for unsigned int values.
> Fix this by using the correct %u format specifier. Cleans up cppcheck
> warnings:
> 
> warning: %d in format string (no. 1) requires 'int' but the argument
> type is 'unsigned int'. [invalidPrintfArgType_sint]
> 
> Signed-off-by: Colin Ian King 

Reviewed-by: Randy Dunlap 
Thanks.

> ---
>  drivers/video/logo/pnmtologo.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/video/logo/pnmtologo.c b/drivers/video/logo/pnmtologo.c
> index ada5ef6e51b7..2434a25afb64 100644
> --- a/drivers/video/logo/pnmtologo.c
> +++ b/drivers/video/logo/pnmtologo.c
> @@ -249,10 +249,10 @@ static void write_footer(void)
>   fputs("\n};\n\n", out);
>   fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname);
>   fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]);
> - fprintf(out, "\t.width\t\t= %d,\n", logo_width);
> - fprintf(out, "\t.height\t\t= %d,\n", logo_height);
> + fprintf(out, "\t.width\t\t= %u,\n", logo_width);
> + fprintf(out, "\t.height\t\t= %u,\n", logo_height);
>   if (logo_type == LINUX_LOGO_CLUT224) {
> - fprintf(out, "\t.clutsize\t= %d,\n", logo_clutsize);
> + fprintf(out, "\t.clutsize\t= %u,\n", logo_clutsize);
>   fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname);
>   }
>   fprintf(out, "\t.data\t\t= %s_data\n", logoname);

-- 
#Randy
https://people.kernel.org/tglx/notes-about-netiquette
https://subspace.kernel.org/etiquette.html


[PATCH v3 4/4] drm/ssd130x: Add support for the SSD133x OLED controller family

2023-12-19 Thread Javier Martinez Canillas
The Solomon SSD133x controllers (such as the SSD1331) are used by RGB dot
matrix OLED panels, add a modesetting pipeline to support the chip family.

The SSD133x controllers support 256 (8-bit) and 65k (16-bit) color depths
but only the former is implemented for now. This is because the 256 color
depth format matches a fourcc code already present in DRM (RGB8), but the
65k pixel format does not match the existing RG16 fourcc code format.

Instead of a R:G:B 5:6:5, the controller expects the 16-bit pixels to be
R:G:B 6:5:6, and so a new fourcc needs to be added to support this format.

Signed-off-by: Javier Martinez Canillas 
---

(no changes since v1)

 drivers/gpu/drm/solomon/ssd130x-i2c.c |   5 +
 drivers/gpu/drm/solomon/ssd130x-spi.c |   7 +
 drivers/gpu/drm/solomon/ssd130x.c | 370 ++
 drivers/gpu/drm/solomon/ssd130x.h |   5 +-
 4 files changed, 386 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c 
b/drivers/gpu/drm/solomon/ssd130x-i2c.c
index f2ccab9c06d9..a047dbec4e48 100644
--- a/drivers/gpu/drm/solomon/ssd130x-i2c.c
+++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c
@@ -105,6 +105,11 @@ static const struct of_device_id ssd130x_of_match[] = {
.compatible = "solomon,ssd1327",
.data = _variants[SSD1327_ID],
},
+   /* ssd133x family */
+   {
+   .compatible = "solomon,ssd1331",
+   .data = _variants[SSD1331_ID],
+   },
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, ssd130x_of_match);
diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c 
b/drivers/gpu/drm/solomon/ssd130x-spi.c
index 84e035a7ab3f..84bfde31d172 100644
--- a/drivers/gpu/drm/solomon/ssd130x-spi.c
+++ b/drivers/gpu/drm/solomon/ssd130x-spi.c
@@ -142,6 +142,11 @@ static const struct of_device_id ssd130x_of_match[] = {
.compatible = "solomon,ssd1327",
.data = _variants[SSD1327_ID],
},
+   /* ssd133x family */
+   {
+   .compatible = "solomon,ssd1331",
+   .data = _variants[SSD1331_ID],
+   },
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, ssd130x_of_match);
@@ -166,6 +171,8 @@ static const struct spi_device_id ssd130x_spi_table[] = {
{ "ssd1322", SSD1322_ID },
{ "ssd1325", SSD1325_ID },
{ "ssd1327", SSD1327_ID },
+   /* ssd133x family */
+   { "ssd1331", SSD1331_ID },
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(spi, ssd130x_spi_table);
diff --git a/drivers/gpu/drm/solomon/ssd130x.c 
b/drivers/gpu/drm/solomon/ssd130x.c
index bef293922b98..447d0c7c88c6 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -119,6 +119,26 @@
 #define SSD130X_SET_VCOMH_VOLTAGE  0xbe
 #define SSD132X_SET_FUNCTION_SELECT_B  0xd5
 
+/* ssd133x commands */
+#define SSD133X_SET_COL_RANGE  0x15
+#define SSD133X_SET_ROW_RANGE  0x75
+#define SSD133X_CONTRAST_A 0x81
+#define SSD133X_CONTRAST_B 0x82
+#define SSD133X_CONTRAST_C 0x83
+#define SSD133X_SET_MASTER_CURRENT 0x87
+#define SSD132X_SET_PRECHARGE_A0x8a
+#define SSD132X_SET_PRECHARGE_B0x8b
+#define SSD132X_SET_PRECHARGE_C0x8c
+#define SSD133X_SET_DISPLAY_START  0xa1
+#define SSD133X_SET_DISPLAY_OFFSET 0xa2
+#define SSD133X_SET_DISPLAY_NORMAL 0xa4
+#define SSD133X_SET_MASTER_CONFIG  0xad
+#define SSD133X_POWER_SAVE_MODE0xb0
+#define SSD133X_PHASES_PERIOD  0xb1
+#define SSD133X_SET_CLOCK_FREQ 0xb3
+#define SSD133X_SET_PRECHARGE_VOLTAGE  0xbb
+#define SSD133X_SET_VCOMH_VOLTAGE  0xbe
+
 #define MAX_CONTRAST 255
 
 const struct ssd130x_deviceinfo ssd130x_variants[] = {
@@ -180,6 +200,12 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = {
.default_width = 128,
.default_height = 128,
.family_id = SSD132X_FAMILY,
+   },
+   /* ssd133x family */
+   [SSD1331_ID] = {
+   .default_width = 96,
+   .default_height = 64,
+   .family_id = SSD133X_FAMILY,
}
 };
 EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X);
@@ -589,6 +615,117 @@ static int ssd132x_init(struct ssd130x_device *ssd130x)
return 0;
 }
 
+static int ssd133x_init(struct ssd130x_device *ssd130x)
+{
+   int ret;
+
+   /* Set color A contrast */
+   ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_CONTRAST_A, 0x91);
+   if (ret < 0)
+   return ret;
+
+   /* Set color B contrast */
+   ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_CONTRAST_B, 0x50);
+   if (ret < 0)
+   return ret;
+
+   /* Set color C contrast */
+   ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_CONTRAST_C, 0x7d);
+   if (ret < 

[PATCH v3 3/4] dt-bindings: display: Add SSD133x OLED controllers

2023-12-19 Thread Javier Martinez Canillas
Add a Device Tree binding schema for the OLED panels based on the
Solomon SSD133x family of controllers.

Signed-off-by: Javier Martinez Canillas 
---

Changes in v3:
- Move solomon,ssd-common.yaml ref before the properties section and
  width/height constraints after the other properties (Conor Dooley).

Changes in v2:
- Unconditionally set the width and height constraints (Conor Dooley).
- Fix indentation in the DTS examples (Krzysztof Kozlowski).

 .../bindings/display/solomon,ssd133x.yaml | 57 +++
 1 file changed, 57 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/solomon,ssd133x.yaml

diff --git a/Documentation/devicetree/bindings/display/solomon,ssd133x.yaml 
b/Documentation/devicetree/bindings/display/solomon,ssd133x.yaml
new file mode 100644
index ..e93879b3da5d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/solomon,ssd133x.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/solomon,ssd133x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Solomon SSD133x OLED Display Controllers
+
+maintainers:
+  - Javier Martinez Canillas 
+
+allOf:
+  - $ref: solomon,ssd-common.yaml#
+
+properties:
+  compatible:
+enum:
+  - solomon,ssd1331
+
+  solomon,width:
+default: 96
+
+  solomon,height:
+default: 64
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+
+oled@3c {
+compatible = "solomon,ssd1331";
+reg = <0x3c>;
+reset-gpios = < 7>;
+};
+
+};
+  - |
+spi {
+#address-cells = <1>;
+#size-cells = <0>;
+
+oled@0 {
+compatible = "solomon,ssd1331";
+reg = <0x0>;
+reset-gpios = < 7>;
+dc-gpios = < 8>;
+spi-max-frequency = <1000>;
+};
+};
-- 
2.43.0



[PATCH v3 2/4] dt-bindings: display: ssd132x: Add vendor prefix to width and height

2023-12-19 Thread Javier Martinez Canillas
Commit 2d23e7d6bacb ("dt-bindings: display: Add SSD132x OLED controllers")
used the wrong properties for width and height, instead of the correct
"solomon,width" and "solomon,height" properties.

Fix this by adding the vendor prefix to the width and height properties.

Fixes: 2d23e7d6bacb ("dt-bindings: display: Add SSD132x OLED controllers")
Reported-by: Conor Dooley 
Closes: 
https://lore.kernel.org/dri-devel/20231218-example-envision-b41ca8efa251@spud/
Signed-off-by: Javier Martinez Canillas 
---

(no changes since v1)

 .../devicetree/bindings/display/solomon,ssd132x.yaml | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml 
b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml
index 37975ee61c5a..dd7939989cf4 100644
--- a/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml
+++ b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml
@@ -30,9 +30,9 @@ allOf:
 const: solomon,ssd1322
 then:
   properties:
-width:
+solomon,width:
   default: 480
-height:
+solomon,height:
   default: 128
 
   - if:
@@ -42,9 +42,9 @@ allOf:
 const: solomon,ssd1325
 then:
   properties:
-width:
+solomon,width:
   default: 128
-height:
+solomon,height:
   default: 80
 
   - if:
@@ -54,9 +54,9 @@ allOf:
 const: solomon,ssd1327
 then:
   properties:
-width:
+solomon,width:
   default: 128
-height:
+solomon,height:
   default: 128
 
 unevaluatedProperties: false
-- 
2.43.0



[PATCH v3 1/4] dt-bindings: display: ssd1307fb: Add vendor prefix to width and height

2023-12-19 Thread Javier Martinez Canillas
The commit 591825fba8a2 ("dt-bindings: display: ssd1307fb: Remove default
width and height values") used the wrong properties for width and height,
instead of the correct "solomon,width" and "solomon,height" properties.

Fix this by adding the vendor prefix to the width and height properties.

Fixes: 591825fba8a2 ("dt-bindings: display: ssd1307fb: Remove default width and 
height values")
Reported-by: Conor Dooley 
Closes: 
https://lore.kernel.org/dri-devel/20231218-example-envision-b41ca8efa251@spud/
Signed-off-by: Javier Martinez Canillas 
---

(no changes since v1)

 .../bindings/display/solomon,ssd1307fb.yaml   | 20 +--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml 
b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
index 3afbb52d1b7f..153ff86fb405 100644
--- a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
+++ b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
@@ -131,9 +131,9 @@ allOf:
 const: sinowealth,sh1106
 then:
   properties:
-width:
+solomon,width:
   default: 132
-height:
+solomon,height:
   default: 64
 solomon,dclk-div:
   default: 1
@@ -149,9 +149,9 @@ allOf:
   - solomon,ssd1305
 then:
   properties:
-width:
+solomon,width:
   default: 132
-height:
+solomon,height:
   default: 64
 solomon,dclk-div:
   default: 1
@@ -167,9 +167,9 @@ allOf:
   - solomon,ssd1306
 then:
   properties:
-width:
+solomon,width:
   default: 128
-height:
+solomon,height:
   default: 64
 solomon,dclk-div:
   default: 1
@@ -185,9 +185,9 @@ allOf:
   - solomon,ssd1307
 then:
   properties:
-width:
+solomon,width:
   default: 128
-height:
+solomon,height:
   default: 39
 solomon,dclk-div:
   default: 2
@@ -205,9 +205,9 @@ allOf:
   - solomon,ssd1309
 then:
   properties:
-width:
+solomon,width:
   default: 128
-height:
+solomon,height:
   default: 64
 solomon,dclk-div:
   default: 1
-- 
2.43.0



[PATCH v3 0/4] drm/solomon: Add support for the SSD133x controller family

2023-12-19 Thread Javier Martinez Canillas
Hello,

This patch-set adds support for the family of SSD133x Solomon controllers,
such as the SSD1331. These are used for RGB Dot Matrix OLED/PLED panels.

This is a v3 that addresses issues pointed out in v2:

https://lore.kernel.org/dri-devel/20231218132045.2066576-1-javi...@redhat.com/

The patches were tested on a Waveshare SSD1331 display using glmark2-drm,
fbcon, fbtests and the retroarch emulator. The binding schema were tested
using the `make W=1 dt_binding_check` target.

Patch #1 and #2 are fixes for the DT binding schema of the existing SSD130x
and SSD132x families.

Patch #3 adds a DT binding schema for the SSD133x controllers and patch #4
extends the ssd130x DRM driver to support the SSD133x controller family.

Best regards,
Javier

Changes in v3:
- Move solomon,ssd-common.yaml ref before the properties section and
  width/height constraints after the other properties (Conor Dooley).

Changes in v2:
- Unconditionally set the width and height constraints (Conor Dooley).
- Fix indentation in the DTS examples (Krzysztof Kozlowski).

Javier Martinez Canillas (4):
  dt-bindings: display: ssd1307fb: Add vendor prefix to width and height
  dt-bindings: display: ssd132x: Add vendor prefix to width and height
  dt-bindings: display: Add SSD133x OLED controllers
  drm/ssd130x: Add support for the SSD133x OLED controller family

 .../bindings/display/solomon,ssd1307fb.yaml   |  20 +-
 .../bindings/display/solomon,ssd132x.yaml |  12 +-
 .../bindings/display/solomon,ssd133x.yaml |  57 +++
 drivers/gpu/drm/solomon/ssd130x-i2c.c |   5 +
 drivers/gpu/drm/solomon/ssd130x-spi.c |   7 +
 drivers/gpu/drm/solomon/ssd130x.c | 370 ++
 drivers/gpu/drm/solomon/ssd130x.h |   5 +-
 7 files changed, 459 insertions(+), 17 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/solomon,ssd133x.yaml

-- 
2.43.0



[PATCH] drm/i915/guc: Avoid circular locking issue on busyness flush

2023-12-19 Thread John . C . Harrison
From: John Harrison 

Avoid the following lockdep complaint:
<4> [298.856498] ==
<4> [298.856500] WARNING: possible circular locking dependency detected
<4> [298.856503] 6.7.0-rc5-CI_DRM_14017-g58ac4ffc75b6+ #1 Tainted: G
N
<4> [298.856505] --
<4> [298.856507] kworker/4:1H/190 is trying to acquire lock:
<4> [298.856509] 8881103e9978 (>reset.backoff_srcu){}-{0:0}, at:
_intel_gt_reset_lock+0x35/0x380 [i915]
<4> [298.856661]
but task is already holding lock:
<4> [298.856663] c900013f7e58
((work_completion)(&(>timestamp.work)->work)){+.+.}-{0:0}, at:
process_scheduled_works+0x264/0x530
<4> [298.856671]
which lock already depends on the new lock.

The complaint is not actually valid. The busyness worker thread does
indeed hold the worker lock and then attempt to acquire the reset lock
(which may have happened in reverse order elsewhere). However, it does
so with a trylock that exits if the reset lock is not available
(specifically to prevent this and other similar deadlocks).
Unfortunately, lockdep does not understand the trylock semantics (the
lock is an i915 specific custom implementation for resets).

Not doing a synchronous flush of the worker thread when a reset is in
progress resolves the lockdep splat by never even attempting to grab
the lock in this particular scenario.

There are situatons where a synchronous cancel is required, however.
So, always do the synchronous cancel if not in reset. And add an extra
synchronous cancel to the end of the reset flow to account for when a
reset is occurring at driver shutdown and the cancel is no longer
synchronous but could lead to unallocated memory accesses if the
worker is not stopped.

Signed-off-by: Zhanjun Dong 
Signed-off-by: John Harrison 
Cc: Andi Shyti 
Cc: Daniel Vetter 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 48 ++-
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  2 +-
 2 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index a259f1118c5ab..0228a77d456ed 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1362,7 +1362,45 @@ static void guc_enable_busyness_worker(struct intel_guc 
*guc)
 
 static void guc_cancel_busyness_worker(struct intel_guc *guc)
 {
-   cancel_delayed_work_sync(>timestamp.work);
+   /*
+* There are many different call stacks that can get here. Some of them
+* hold the reset mutex. The busyness worker also attempts to acquire 
the
+* reset mutex. Synchronously flushing a worker thread requires 
acquiring
+* the worker mutex. Lockdep sees this as a conflict. It thinks that the
+* flush can deadlock because it holds the worker mutex while waiting 
for
+* the reset mutex, but another thread is holding the reset mutex and 
might
+* attempt to use other worker functions.
+*
+* In practice, this scenario does not exist because the busyness worker
+* does not block waiting for the reset mutex. It does a try-lock on it 
and
+* immediately exits if the lock is already held. Unfortunately, the 
mutex
+* in question (I915_RESET_BACKOFF) is an i915 implementation which has 
lockdep
+* annotation but not to the extent of explaining the 'might lock' is 
also a
+* 'does not need to lock'. So one option would be to add more complex 
lockdep
+* annotations to ignore the issue (if at all possible). A simpler 
option is to
+* just not flush synchronously when a rest in progress. Given that the 
worker
+* will just early exit and re-schedule itself anyway, there is no 
advantage
+* to running it immediately.
+*
+* If a reset is not in progress, then the synchronous flush may be 
required.
+* As noted many call stacks lead here, some during suspend and driver 
unload
+* which do require a synchronous flush to make sure the worker is 
stopped
+* before memory is freed.
+*
+* Trying to pass a 'need_sync' or 'in_reset' flag all the way down 
through
+* every possible call stack is unfeasible. It would be too intrusive 
to many
+* areas that really don't care about the GuC backend. However, there 
is the
+* 'reset_in_progress' flag available, so just use that.
+*
+* And note that in the case of a reset occurring during driver unload
+* (wedge_on_fini), skipping the cancel in _prepare (when the reset 
flag is set
+* is fine because there is another cancel in _finish (when the reset 
flag is
+* not).
+*/
+   if (guc_to_gt(guc)->uc.reset_in_progress)
+   cancel_delayed_work(>timestamp.work);
+   else
+   

Re: [RFC PATCH v3 04/23] drm/vkms: Add kunit tests for VKMS LUT handling

2023-12-19 Thread Harry Wentland



On 2023-12-07 09:30, Pekka Paalanen wrote:
> On Wed, 8 Nov 2023 11:36:23 -0500
> Harry Wentland  wrote:
> 
>> Debugging LUT math is much easier when we can unit test
>> it. Add kunit functionality to VKMS and add tests for
>>  - get_lut_index
>>  - lerp_u16
>>
>> v3:
>>  - Use include way of testing static functions (Arthur)
>>
>> Signed-off-by: Harry Wentland 
>> Cc: Arthur Grillo 
>> ---
>>  drivers/gpu/drm/vkms/Kconfig  |  5 ++
>>  drivers/gpu/drm/vkms/tests/.kunitconfig   |  4 ++
>>  drivers/gpu/drm/vkms/tests/vkms_color_tests.c | 62 +++
>>  drivers/gpu/drm/vkms/vkms_composer.c  |  8 ++-
>>  4 files changed, 77 insertions(+), 2 deletions(-)
>>  create mode 100644 drivers/gpu/drm/vkms/tests/.kunitconfig
>>  create mode 100644 drivers/gpu/drm/vkms/tests/vkms_color_tests.c
>>
>> diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig
>> index b9ecdebecb0b..c1f8b343ff0e 100644
>> --- a/drivers/gpu/drm/vkms/Kconfig
>> +++ b/drivers/gpu/drm/vkms/Kconfig
>> @@ -13,3 +13,8 @@ config DRM_VKMS
>>a VKMS.
>>  
>>If M is selected the module will be called vkms.
>> +
>> +config DRM_VKMS_KUNIT_TESTS
>> +tristate "Tests for VKMS" if !KUNIT_ALL_TESTS
>> +depends on DRM_VKMS && KUNIT
>> +default KUNIT_ALL_TESTS
>> diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig 
>> b/drivers/gpu/drm/vkms/tests/.kunitconfig
>> new file mode 100644
>> index ..70e378228cbd
>> --- /dev/null
>> +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
>> @@ -0,0 +1,4 @@
>> +CONFIG_KUNIT=y
>> +CONFIG_DRM=y
>> +CONFIG_DRM_VKMS=y
>> +CONFIG_DRM_VKMS_KUNIT_TESTS=y
>> diff --git a/drivers/gpu/drm/vkms/tests/vkms_color_tests.c 
>> b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
>> new file mode 100644
>> index ..b995114cf6b8
>> --- /dev/null
>> +++ b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
>> @@ -0,0 +1,62 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +
>> +#include 
>> +
>> +#include 
>> +
>> +#define TEST_LUT_SIZE 16
>> +
>> +static struct drm_color_lut test_linear_array[TEST_LUT_SIZE] = {
>> +{ 0x0, 0x0, 0x0, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +};
>> +
>> +const struct vkms_color_lut test_linear_lut = {
>> +.base = test_linear_array,
>> +.lut_length = TEST_LUT_SIZE,
>> +.channel_value2index_ratio = 0xf000fll
>> +};
>> +
>> +
>> +static void vkms_color_test_get_lut_index(struct kunit *test)
>> +{
>> +int i;
>> +
>> +KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(_linear_lut, 
>> test_linear_array[0].red)), 0);
>> +
>> +for (i = 0; i < TEST_LUT_SIZE; i++)
>> +KUNIT_EXPECT_EQ(test, 
>> drm_fixp2int_ceil(get_lut_index(_linear_lut, 
>> test_linear_array[i].red)), i);
> 
> Hi,
> 
> what about testing with values not directly hitting a LUT element?
> 
>> +}
>> +
>> +static void vkms_color_test_lerp(struct kunit *test)
>> +{
>> +KUNIT_EXPECT_EQ(test, lerp_u16(0x0, 0x10, 0x8000), 0x8);
> 
> It would raise much more confidence in lerp_u16() if there were more cases:
> - odd a
> - odd b
> - odd b-a
> - b = a
> - b = a + 1
> 
> For each of the above:
> - t = 0.0
> - t = 1.0
> - t = 0.0 + 1
> - t = 1.0 - 1
> - t chosen so that result must round/truncate
> - t chosen to verify the flipping point of result a (or b) to a+1 (or b-1)
> 
> I think those are the fragile points in a lerp implementation.
> 

Good point. Adding the "t = 1.0 - 1" test actually showed a problem
with the lerp_u16 function. I have a fix for it.

Harry

> 
> Thanks,
> pq
> 
>> +}
>> +
>> +static struct kunit_case vkms_color_test_cases[] = {
>> +KUNIT_CASE(vkms_color_test_get_lut_index),
>> +KUNIT_CASE(vkms_color_test_lerp),
>> +{}
>> +};
>> +
>> +static struct kunit_suite vkms_color_test_suite = {
>> +.name = "vkms-color",
>> +.test_cases = vkms_color_test_cases,
>> +};
>> +kunit_test_suite(vkms_color_test_suite);
>> +
>> +MODULE_LICENSE("GPL");
>> \ No newline at end of file
>> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
>> b/drivers/gpu/drm/vkms/vkms_composer.c
>> index 3c99fb8b54e2..6f942896036e 100644
>> --- a/drivers/gpu/drm/vkms/vkms_composer.c
>> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
>> @@ -91,7 +91,7 @@ static void fill_background(const struct pixel_argb_u16 
>> *background_color,
>>  }
>>  
>>  // lerp(a, b, t) = a + (b - a) * t
>> -static u16 lerp_u16(u16 a, u16 b, s64 t)
>> +u16 lerp_u16(u16 a, u16 b, s64 t)
>>  {
>>  s64 a_fp = 

Re: [PATCH] drm/amd/display: remove redundant initialization of variable remainder

2023-12-19 Thread Alex Deucher
Applied.  Thanks!

On Tue, Dec 19, 2023 at 12:40 PM Colin Ian King  wrote:
>
> Variable remainder is being initialized with a value that is never read,
> the assignment is redundant and can be removed. Also add a newline
> after the declaration to clean up the coding style.
>
> Signed-off-by: Colin Ian King 
> ---
>  drivers/gpu/drm/amd/display/dc/basics/conversion.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/basics/conversion.c 
> b/drivers/gpu/drm/amd/display/dc/basics/conversion.c
> index e295a839ab47..1090d235086a 100644
> --- a/drivers/gpu/drm/amd/display/dc/basics/conversion.c
> +++ b/drivers/gpu/drm/amd/display/dc/basics/conversion.c
> @@ -103,7 +103,8 @@ void convert_float_matrix(
>
>  static uint32_t find_gcd(uint32_t a, uint32_t b)
>  {
> -   uint32_t remainder = 0;
> +   uint32_t remainder;
> +
> while (b != 0) {
> remainder = a % b;
> a = b;
> --
> 2.39.2
>


[PATCH v5 8/8] Documentation: iio: Document high-speed DMABUF based API

2023-12-19 Thread Paul Cercueil
Document the new DMABUF based API.

Signed-off-by: Paul Cercueil 

---
v2: - Explicitly state that the new interface is optional and is
  not implemented by all drivers.
- The IOCTLs can now only be called on the buffer FD returned by
  IIO_BUFFER_GET_FD_IOCTL.
- Move the page up a bit in the index since it is core stuff and not
  driver-specific.

v3: Update the documentation to reflect the new API.

v5: Use description lists for the documentation of the three new IOCTLs
instead of abusing subsections.
---
 Documentation/iio/dmabuf_api.rst | 54 
 Documentation/iio/index.rst  |  2 ++
 2 files changed, 56 insertions(+)
 create mode 100644 Documentation/iio/dmabuf_api.rst

diff --git a/Documentation/iio/dmabuf_api.rst b/Documentation/iio/dmabuf_api.rst
new file mode 100644
index ..1cd6cd51a582
--- /dev/null
+++ b/Documentation/iio/dmabuf_api.rst
@@ -0,0 +1,54 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===
+High-speed DMABUF interface for IIO
+===
+
+1. Overview
+===
+
+The Industrial I/O subsystem supports access to buffers through a
+file-based interface, with read() and write() access calls through the
+IIO device's dev node.
+
+It additionally supports a DMABUF based interface, where the userspace
+can attach DMABUF objects (externally created) to a IIO buffer, and
+subsequently use them for data transfers.
+
+A userspace application can then use this interface to share DMABUF
+objects between several interfaces, allowing it to transfer data in a
+zero-copy fashion, for instance between IIO and the USB stack.
+
+The userspace application can also memory-map the DMABUF objects, and
+access the sample data directly. The advantage of doing this vs. the
+read() interface is that it avoids an extra copy of the data between the
+kernel and userspace. This is particularly useful for high-speed devices
+which produce several megabytes or even gigabytes of data per second.
+It does however increase the userspace-kernelspace synchronization
+overhead, as the DMA_BUF_SYNC_START and DMA_BUF_SYNC_END IOCTLs have to
+be used for data integrity.
+
+2. User API
+===
+
+As part of this interface, three new IOCTLs have been added. These three
+IOCTLs have to be performed on the IIO buffer's file descriptor,
+obtained using the IIO_BUFFER_GET_FD_IOCTL() ioctl.
+
+  ``IIO_BUFFER_DMABUF_ATTACH_IOCTL(int)``
+Attach the DMABUF object, identified by its file descriptor, to the
+IIO buffer. Returns zero on success, and a negative errno value on
+error.
+
+  ``IIO_BUFFER_DMABUF_DETACH_IOCTL(int)``
+Detach the given DMABUF object, identified by its file descriptor,
+from the IIO buffer. Returns zero on success, and a negative errno
+value on error.
+
+Note that closing the IIO buffer's file descriptor will
+automatically detach all previously attached DMABUF objects.
+
+  ``IIO_BUFFER_DMABUF_ENQUEUE_IOCTL(struct iio_dmabuf *iio_dmabuf)``
+Enqueue a previously attached DMABUF object to the buffer queue.
+Enqueued DMABUFs will be read from (if output buffer) or written to
+(if input buffer) as long as the buffer is enabled.
diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst
index 1b7292c58cd0..3eae8fcb1938 100644
--- a/Documentation/iio/index.rst
+++ b/Documentation/iio/index.rst
@@ -9,6 +9,8 @@ Industrial I/O
 
iio_configfs
 
+   dmabuf_api
+
ep93xx_adc
 
bno055
-- 
2.43.0



[PATCH v5 7/8] iio: buffer-dmaengine: Support new DMABUF based userspace API

2023-12-19 Thread Paul Cercueil
Use the functions provided by the buffer-dma core to implement the
DMABUF userspace API in the buffer-dmaengine IIO buffer implementation.

Since we want to be able to transfer an arbitrary number of bytes and
not necesarily the full DMABUF, the associated scatterlist is converted
to an array of DMA addresses + lengths, which is then passed to
dmaengine_prep_slave_dma_array().

Signed-off-by: Paul Cercueil 

---
v3: Use the new dmaengine_prep_slave_dma_array(), and adapt the code to
work with the new functions introduced in industrialio-buffer-dma.c.

v5: - Use the new dmaengine_prep_slave_dma_vec().
- Restrict to input buffers, since output buffers are not yet
  supported by IIO buffers.
---
 .../buffer/industrialio-buffer-dmaengine.c| 52 ---
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c 
b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
index 5f85ba38e6f6..825d76a24a67 100644
--- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c
+++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
@@ -64,15 +64,51 @@ static int iio_dmaengine_buffer_submit_block(struct 
iio_dma_buffer_queue *queue,
struct dmaengine_buffer *dmaengine_buffer =
iio_buffer_to_dmaengine_buffer(>buffer);
struct dma_async_tx_descriptor *desc;
+   unsigned int i, nents;
+   struct scatterlist *sgl;
+   struct dma_vec *vecs;
+   size_t max_size;
dma_cookie_t cookie;
+   size_t len_total;
 
-   block->bytes_used = min(block->size, dmaengine_buffer->max_size);
-   block->bytes_used = round_down(block->bytes_used,
-   dmaengine_buffer->align);
+   if (queue->buffer.direction != IIO_BUFFER_DIRECTION_IN) {
+   /* We do not yet support output buffers. */
+   return -EINVAL;
+   }
 
-   desc = dmaengine_prep_slave_single(dmaengine_buffer->chan,
-   block->phys_addr, block->bytes_used, DMA_DEV_TO_MEM,
-   DMA_PREP_INTERRUPT);
+   if (block->sg_table) {
+   sgl = block->sg_table->sgl;
+   nents = sg_nents_for_len(sgl, block->bytes_used);
+
+   vecs = kmalloc_array(nents, sizeof(*vecs), GFP_KERNEL);
+   if (!vecs)
+   return -ENOMEM;
+
+   len_total = block->bytes_used;
+
+   for (i = 0; i < nents; i++) {
+   vecs[i].addr = sg_dma_address(sgl);
+   vecs[i].len = min(sg_dma_len(sgl), len_total);
+   len_total -= vecs[i].len;
+
+   sgl = sg_next(sgl);
+   }
+
+   desc = dmaengine_prep_slave_dma_vec(dmaengine_buffer->chan,
+   vecs, nents, DMA_DEV_TO_MEM,
+   DMA_PREP_INTERRUPT);
+   kfree(vecs);
+   } else {
+   max_size = min(block->size, dmaengine_buffer->max_size);
+   max_size = round_down(max_size, dmaengine_buffer->align);
+   block->bytes_used = max_size;
+
+   desc = dmaengine_prep_slave_single(dmaengine_buffer->chan,
+  block->phys_addr,
+  block->bytes_used,
+  DMA_DEV_TO_MEM,
+  DMA_PREP_INTERRUPT);
+   }
if (!desc)
return -ENOMEM;
 
@@ -120,6 +156,10 @@ static const struct iio_buffer_access_funcs 
iio_dmaengine_buffer_ops = {
.data_available = iio_dma_buffer_data_available,
.release = iio_dmaengine_buffer_release,
 
+   .enqueue_dmabuf = iio_dma_buffer_enqueue_dmabuf,
+   .attach_dmabuf = iio_dma_buffer_attach_dmabuf,
+   .detach_dmabuf = iio_dma_buffer_detach_dmabuf,
+
.modes = INDIO_BUFFER_HARDWARE,
.flags = INDIO_BUFFER_FLAG_FIXED_WATERMARK,
 };
-- 
2.43.0



[PATCH v5 6/8] iio: buffer-dma: Enable support for DMABUFs

2023-12-19 Thread Paul Cercueil
Implement iio_dma_buffer_attach_dmabuf(), iio_dma_buffer_detach_dmabuf()
and iio_dma_buffer_transfer_dmabuf(), which can then be used by the IIO
DMA buffer implementations.

Signed-off-by: Paul Cercueil 

---
v3: Update code to provide the functions that will be used as callbacks
for the new IOCTLs.
---
 drivers/iio/buffer/industrialio-buffer-dma.c | 157 +--
 include/linux/iio/buffer-dma.h   |  26 +++
 2 files changed, 170 insertions(+), 13 deletions(-)

diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c 
b/drivers/iio/buffer/industrialio-buffer-dma.c
index 5610ba67925e..adb64f975064 100644
--- a/drivers/iio/buffer/industrialio-buffer-dma.c
+++ b/drivers/iio/buffer/industrialio-buffer-dma.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -94,14 +95,24 @@ static void iio_buffer_block_release(struct kref *kref)
 {
struct iio_dma_buffer_block *block = container_of(kref,
struct iio_dma_buffer_block, kref);
+   struct iio_dma_buffer_queue *queue = block->queue;
 
-   WARN_ON(block->state != IIO_BLOCK_STATE_DEAD);
+   WARN_ON(block->fileio && block->state != IIO_BLOCK_STATE_DEAD);
 
-   dma_free_coherent(block->queue->dev, PAGE_ALIGN(block->size),
-   block->vaddr, block->phys_addr);
+   mutex_lock(>lock);
 
-   iio_buffer_put(>queue->buffer);
+   if (block->fileio) {
+   dma_free_coherent(queue->dev, PAGE_ALIGN(block->size),
+ block->vaddr, block->phys_addr);
+   queue->num_fileio_blocks--;
+   }
+
+   queue->num_blocks--;
kfree(block);
+
+   mutex_unlock(>lock);
+
+   iio_buffer_put(>buffer);
 }
 
 static void iio_buffer_block_get(struct iio_dma_buffer_block *block)
@@ -163,7 +174,7 @@ static struct iio_dma_buffer_queue 
*iio_buffer_to_queue(struct iio_buffer *buf)
 }
 
 static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block(
-   struct iio_dma_buffer_queue *queue, size_t size)
+   struct iio_dma_buffer_queue *queue, size_t size, bool fileio)
 {
struct iio_dma_buffer_block *block;
 
@@ -171,13 +182,16 @@ static struct iio_dma_buffer_block 
*iio_dma_buffer_alloc_block(
if (!block)
return NULL;
 
-   block->vaddr = dma_alloc_coherent(queue->dev, PAGE_ALIGN(size),
-   >phys_addr, GFP_KERNEL);
-   if (!block->vaddr) {
-   kfree(block);
-   return NULL;
+   if (fileio) {
+   block->vaddr = dma_alloc_coherent(queue->dev, PAGE_ALIGN(size),
+ >phys_addr, 
GFP_KERNEL);
+   if (!block->vaddr) {
+   kfree(block);
+   return NULL;
+   }
}
 
+   block->fileio = fileio;
block->size = size;
block->state = IIO_BLOCK_STATE_DONE;
block->queue = queue;
@@ -186,6 +200,9 @@ static struct iio_dma_buffer_block 
*iio_dma_buffer_alloc_block(
 
iio_buffer_get(>buffer);
 
+   queue->num_blocks++;
+   queue->num_fileio_blocks += fileio;
+
return block;
 }
 
@@ -211,6 +228,9 @@ void iio_dma_buffer_block_done(struct iio_dma_buffer_block 
*block)
_iio_dma_buffer_block_done(block);
spin_unlock_irqrestore(>list_lock, flags);
 
+   if (!block->fileio)
+   iio_buffer_signal_dmabuf_done(block->attach, 0);
+
iio_buffer_block_put_atomic(block);
wake_up_interruptible_poll(>buffer.pollq, EPOLLIN | EPOLLRDNORM);
 }
@@ -237,10 +257,14 @@ void iio_dma_buffer_block_list_abort(struct 
iio_dma_buffer_queue *queue,
list_del(>head);
block->bytes_used = 0;
_iio_dma_buffer_block_done(block);
+
+   if (!block->fileio)
+   iio_buffer_signal_dmabuf_done(block->attach, -EINTR);
iio_buffer_block_put_atomic(block);
}
spin_unlock_irqrestore(>list_lock, flags);
 
+   queue->fileio.enabled = false;
wake_up_interruptible_poll(>buffer.pollq, EPOLLIN | EPOLLRDNORM);
 }
 EXPORT_SYMBOL_GPL(iio_dma_buffer_block_list_abort);
@@ -261,6 +285,12 @@ static bool iio_dma_block_reusable(struct 
iio_dma_buffer_block *block)
}
 }
 
+static bool iio_dma_buffer_fileio_mode(struct iio_dma_buffer_queue *queue)
+{
+   return queue->fileio.enabled ||
+   queue->num_blocks == queue->num_fileio_blocks;
+}
+
 /**
  * iio_dma_buffer_request_update() - DMA buffer request_update callback
  * @buffer: The buffer which to request an update
@@ -287,6 +317,12 @@ int iio_dma_buffer_request_update(struct iio_buffer 
*buffer)
 
mutex_lock(>lock);
 
+   queue->fileio.enabled = iio_dma_buffer_fileio_mode(queue);
+
+   /* If DMABUFs were created, disable fileio interface */
+   if (!queue->fileio.enabled)
+   goto out_unlock;
+
/* Allocations are page 

[PATCH v5 5/8] iio: core: Add new DMABUF interface infrastructure

2023-12-19 Thread Paul Cercueil
Add the necessary infrastructure to the IIO core to support a new
optional DMABUF based interface.

With this new interface, DMABUF objects (externally created) can be
attached to a IIO buffer, and subsequently used for data transfer.

A userspace application can then use this interface to share DMABUF
objects between several interfaces, allowing it to transfer data in a
zero-copy fashion, for instance between IIO and the USB stack.

The userspace application can also memory-map the DMABUF objects, and
access the sample data directly. The advantage of doing this vs. the
read() interface is that it avoids an extra copy of the data between the
kernel and userspace. This is particularly userful for high-speed
devices which produce several megabytes or even gigabytes of data per
second.

As part of the interface, 3 new IOCTLs have been added:

IIO_BUFFER_DMABUF_ATTACH_IOCTL(int fd):
 Attach the DMABUF object identified by the given file descriptor to the
 buffer.

IIO_BUFFER_DMABUF_DETACH_IOCTL(int fd):
 Detach the DMABUF object identified by the given file descriptor from
 the buffer. Note that closing the IIO buffer's file descriptor will
 automatically detach all previously attached DMABUF objects.

IIO_BUFFER_DMABUF_ENQUEUE_IOCTL(struct iio_dmabuf *):
 Request a data transfer to/from the given DMABUF object. Its file
 descriptor, as well as the transfer size and flags are provided in the
 "iio_dmabuf" structure.

These three IOCTLs have to be performed on the IIO buffer's file
descriptor, obtained using the IIO_BUFFER_GET_FD_IOCTL() ioctl.

Signed-off-by: Paul Cercueil 

---
v2: Only allow the new IOCTLs on the buffer FD created with
IIO_BUFFER_GET_FD_IOCTL().

v3: - Get rid of the old IOCTLs. The IIO subsystem does not create or
manage DMABUFs anymore, and only attaches/detaches externally
created DMABUFs.
- Add IIO_BUFFER_DMABUF_CYCLIC to the supported flags.

v5: - Use dev_err() instead of pr_err()
- Inline to_iio_dma_fence()
- Add comment to explain why we unref twice when detaching dmabuf
- Remove TODO comment. It is actually safe to free the file's
  private data even when transfers are still pending because it
  won't be accessed.
- Fix documentation of new fields in struct iio_buffer_access_funcs
- iio_dma_resv_lock() does not need to be exported, make it static
---
 drivers/iio/industrialio-buffer.c | 402 ++
 include/linux/iio/buffer_impl.h   |  26 ++
 include/uapi/linux/iio/buffer.h   |  22 ++
 3 files changed, 450 insertions(+)

diff --git a/drivers/iio/industrialio-buffer.c 
b/drivers/iio/industrialio-buffer.c
index 09c41e9ccf87..24c040e073a7 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -13,10 +13,14 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -28,6 +32,31 @@
 #include 
 #include 
 
+#define DMABUF_ENQUEUE_TIMEOUT_MS 5000
+
+struct iio_dma_fence;
+
+struct iio_dmabuf_priv {
+   struct list_head entry;
+   struct kref ref;
+
+   struct iio_buffer *buffer;
+   struct iio_dma_buffer_block *block;
+
+   u64 context;
+   spinlock_t lock;
+
+   struct dma_buf_attachment *attach;
+   struct iio_dma_fence *fence;
+};
+
+struct iio_dma_fence {
+   struct dma_fence base;
+   struct iio_dmabuf_priv *priv;
+   struct sg_table *sgt;
+   enum dma_data_direction dir;
+};
+
 static const char * const iio_endian_prefix[] = {
[IIO_BE] = "be",
[IIO_LE] = "le",
@@ -332,6 +361,7 @@ void iio_buffer_init(struct iio_buffer *buffer)
 {
INIT_LIST_HEAD(>demux_list);
INIT_LIST_HEAD(>buffer_list);
+   INIT_LIST_HEAD(>dmabufs);
init_waitqueue_head(>pollq);
kref_init(>ref);
if (!buffer->watermark)
@@ -1519,14 +1549,54 @@ static void 
iio_buffer_unregister_legacy_sysfs_groups(struct iio_dev *indio_dev)
kfree(iio_dev_opaque->legacy_scan_el_group.attrs);
 }
 
+static void iio_buffer_dmabuf_release(struct kref *ref)
+{
+   struct iio_dmabuf_priv *priv = container_of(ref, struct 
iio_dmabuf_priv, ref);
+   struct dma_buf_attachment *attach = priv->attach;
+   struct iio_buffer *buffer = priv->buffer;
+   struct dma_buf *dmabuf = attach->dmabuf;
+
+   buffer->access->detach_dmabuf(buffer, priv->block);
+
+   dma_buf_detach(attach->dmabuf, attach);
+   dma_buf_put(dmabuf);
+   kfree(priv);
+}
+
+void iio_buffer_dmabuf_get(struct dma_buf_attachment *attach)
+{
+   struct iio_dmabuf_priv *priv = attach->importer_priv;
+
+   kref_get(>ref);
+}
+EXPORT_SYMBOL_GPL(iio_buffer_dmabuf_get);
+
+void iio_buffer_dmabuf_put(struct dma_buf_attachment *attach)
+{
+   struct iio_dmabuf_priv *priv = attach->importer_priv;
+
+   kref_put(>ref, iio_buffer_dmabuf_release);
+}
+EXPORT_SYMBOL_GPL(iio_buffer_dmabuf_put);
+
 static int iio_buffer_chrdev_release(struct 

[PATCH v5 4/8] dmaengine: dma-axi-dmac: Implement device_prep_slave_dma_vec

2023-12-19 Thread Paul Cercueil
Add implementation of the .device_prep_slave_dma_vec() callback.

Signed-off-by: Paul Cercueil 

---
v3: New patch

v5: Implement .device_prep_slave_dma_vec() instead of v3's
.device_prep_slave_dma_array().
---
 drivers/dma/dma-axi-dmac.c | 40 ++
 1 file changed, 40 insertions(+)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index 2457a420c13d..363808088cc5 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -535,6 +535,45 @@ static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct 
axi_dmac_chan *chan,
return sg;
 }
 
+static struct dma_async_tx_descriptor *
+axi_dmac_prep_slave_dma_vec(struct dma_chan *c, const struct dma_vec *vecs,
+   size_t nb, enum dma_transfer_direction direction,
+   unsigned long flags)
+{
+   struct axi_dmac_chan *chan = to_axi_dmac_chan(c);
+   struct axi_dmac_desc *desc;
+   unsigned int num_sgs = 0;
+   struct axi_dmac_sg *dsg;
+   size_t i;
+
+   if (direction != chan->direction)
+   return NULL;
+
+   for (i = 0; i < nb; i++)
+   num_sgs += DIV_ROUND_UP(vecs[i].len, chan->max_length);
+
+   desc = axi_dmac_alloc_desc(num_sgs);
+   if (!desc)
+   return NULL;
+
+   dsg = desc->sg;
+
+   for (i = 0; i < nb; i++) {
+   if (!axi_dmac_check_addr(chan, vecs[i].addr) ||
+   !axi_dmac_check_len(chan, vecs[i].len)) {
+   kfree(desc);
+   return NULL;
+   }
+
+   dsg = axi_dmac_fill_linear_sg(chan, direction, vecs[i].addr, 1,
+ vecs[i].len, dsg);
+   }
+
+   desc->cyclic = false;
+
+   return vchan_tx_prep(>vchan, >vdesc, flags);
+}
+
 static struct dma_async_tx_descriptor *axi_dmac_prep_slave_sg(
struct dma_chan *c, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction direction,
@@ -957,6 +996,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
dma_dev->device_tx_status = dma_cookie_status;
dma_dev->device_issue_pending = axi_dmac_issue_pending;
dma_dev->device_prep_slave_sg = axi_dmac_prep_slave_sg;
+   dma_dev->device_prep_slave_dma_vec = axi_dmac_prep_slave_dma_vec;
dma_dev->device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic;
dma_dev->device_prep_interleaved_dma = axi_dmac_prep_interleaved;
dma_dev->device_terminate_all = axi_dmac_terminate_all;
-- 
2.43.0



[PATCH v5 3/8] dmaengine: Add API function dmaengine_prep_slave_dma_vec()

2023-12-19 Thread Paul Cercueil
This function can be used to initiate a scatter-gather DMA transfer,
where the address and size of each segment is located in one entry of
the dma_vec array.

The major difference with dmaengine_prep_slave_sg() is that it supports
specifying the lengths of each DMA transfer; as trying to override the
length of the transfer with dmaengine_prep_slave_sg() is a very tedious
process. The introduction of a new API function is also justified by the
fact that scatterlists are on their way out.

Note that dmaengine_prep_interleaved_dma() is not helpful either in that
case, as it assumes that the address of each segment will be higher than
the one of the previous segment, which we just cannot guarantee in case
of a scatter-gather transfer.

Signed-off-by: Paul Cercueil 

---
v3: New patch

v5: Replace with function dmaengine_prep_slave_dma_vec(), and struct
'dma_vec'.
Note that at some point we will need to support cyclic transfers
using dmaengine_prep_slave_dma_vec(). Maybe with a new "flags"
parameter to the function?
---
 include/linux/dmaengine.h | 25 +
 1 file changed, 25 insertions(+)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 3df70d6131c8..ee5931ddb42f 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -160,6 +160,16 @@ struct dma_interleaved_template {
struct data_chunk sgl[];
 };
 
+/**
+ * struct dma_vec - DMA vector
+ * @addr: Bus address of the start of the vector
+ * @len: Length in bytes of the DMA vector
+ */
+struct dma_vec {
+   dma_addr_t addr;
+   size_t len;
+};
+
 /**
  * enum dma_ctrl_flags - DMA flags to augment operation preparation,
  *  control completion, and communicate status.
@@ -910,6 +920,10 @@ struct dma_device {
struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)(
struct dma_chan *chan, unsigned long flags);
 
+   struct dma_async_tx_descriptor *(*device_prep_slave_dma_vec)(
+   struct dma_chan *chan, const struct dma_vec *vecs,
+   size_t nents, enum dma_transfer_direction direction,
+   unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
struct dma_chan *chan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction direction,
@@ -972,6 +986,17 @@ static inline struct dma_async_tx_descriptor 
*dmaengine_prep_slave_single(
  dir, flags, NULL);
 }
 
+static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_dma_vec(
+   struct dma_chan *chan, const struct dma_vec *vecs, size_t nents,
+   enum dma_transfer_direction dir, unsigned long flags)
+{
+   if (!chan || !chan->device || !chan->device->device_prep_slave_dma_vec)
+   return NULL;
+
+   return chan->device->device_prep_slave_dma_vec(chan, vecs, nents,
+  dir, flags);
+}
+
 static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg(
struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len,
enum dma_transfer_direction dir, unsigned long flags)
-- 
2.43.0



[PATCH v5 2/8] iio: buffer-dma: split iio_dma_buffer_fileio_free() function

2023-12-19 Thread Paul Cercueil
From: Alexandru Ardelean 

This change splits the logic into a separate function, which will be
re-used later.

Signed-off-by: Alexandru Ardelean 
Cc: Alexandru Ardelean 
Signed-off-by: Paul Cercueil 
---
 drivers/iio/buffer/industrialio-buffer-dma.c | 43 +++-
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c 
b/drivers/iio/buffer/industrialio-buffer-dma.c
index 1fc91467d1aa..5610ba67925e 100644
--- a/drivers/iio/buffer/industrialio-buffer-dma.c
+++ b/drivers/iio/buffer/industrialio-buffer-dma.c
@@ -346,6 +346,29 @@ int iio_dma_buffer_request_update(struct iio_buffer 
*buffer)
 }
 EXPORT_SYMBOL_GPL(iio_dma_buffer_request_update);
 
+static void iio_dma_buffer_fileio_free(struct iio_dma_buffer_queue *queue)
+{
+   unsigned int i;
+
+   spin_lock_irq(>list_lock);
+   for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
+   if (!queue->fileio.blocks[i])
+   continue;
+   queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD;
+   }
+   spin_unlock_irq(>list_lock);
+
+   INIT_LIST_HEAD(>incoming);
+
+   for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
+   if (!queue->fileio.blocks[i])
+   continue;
+   iio_buffer_block_put(queue->fileio.blocks[i]);
+   queue->fileio.blocks[i] = NULL;
+   }
+   queue->fileio.active_block = NULL;
+}
+
 static void iio_dma_buffer_submit_block(struct iio_dma_buffer_queue *queue,
struct iio_dma_buffer_block *block)
 {
@@ -638,27 +661,9 @@ EXPORT_SYMBOL_GPL(iio_dma_buffer_init);
  */
 void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue)
 {
-   unsigned int i;
-
mutex_lock(>lock);
 
-   spin_lock_irq(>list_lock);
-   for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
-   if (!queue->fileio.blocks[i])
-   continue;
-   queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD;
-   }
-   spin_unlock_irq(>list_lock);
-
-   INIT_LIST_HEAD(>incoming);
-
-   for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
-   if (!queue->fileio.blocks[i])
-   continue;
-   iio_buffer_block_put(queue->fileio.blocks[i]);
-   queue->fileio.blocks[i] = NULL;
-   }
-   queue->fileio.active_block = NULL;
+   iio_dma_buffer_fileio_free(queue);
queue->ops = NULL;
 
mutex_unlock(>lock);
-- 
2.43.0



[PATCH v5 1/8] iio: buffer-dma: Get rid of outgoing queue

2023-12-19 Thread Paul Cercueil
The buffer-dma code was using two queues, incoming and outgoing, to
manage the state of the blocks in use.

While this totally works, it adds some complexity to the code,
especially since the code only manages 2 blocks. It is much easier to
just check each block's state manually, and keep a counter for the next
block to dequeue.

Since the new DMABUF based API wouldn't use the outgoing queue anyway,
getting rid of it now makes the upcoming changes simpler.

With this change, the IIO_BLOCK_STATE_DEQUEUED is now useless, and can
be removed.

Signed-off-by: Paul Cercueil 

---
v2: - Only remove the outgoing queue, and keep the incoming queue, as we
  want the buffer to start streaming data as soon as it is enabled.
- Remove IIO_BLOCK_STATE_DEQUEUED, since it is now functionally the
  same as IIO_BLOCK_STATE_DONE.
---
 drivers/iio/buffer/industrialio-buffer-dma.c | 44 ++--
 include/linux/iio/buffer-dma.h   |  7 ++--
 2 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c 
b/drivers/iio/buffer/industrialio-buffer-dma.c
index d348af8b9705..1fc91467d1aa 100644
--- a/drivers/iio/buffer/industrialio-buffer-dma.c
+++ b/drivers/iio/buffer/industrialio-buffer-dma.c
@@ -179,7 +179,7 @@ static struct iio_dma_buffer_block 
*iio_dma_buffer_alloc_block(
}
 
block->size = size;
-   block->state = IIO_BLOCK_STATE_DEQUEUED;
+   block->state = IIO_BLOCK_STATE_DONE;
block->queue = queue;
INIT_LIST_HEAD(>head);
kref_init(>kref);
@@ -191,16 +191,8 @@ static struct iio_dma_buffer_block 
*iio_dma_buffer_alloc_block(
 
 static void _iio_dma_buffer_block_done(struct iio_dma_buffer_block *block)
 {
-   struct iio_dma_buffer_queue *queue = block->queue;
-
-   /*
-* The buffer has already been freed by the application, just drop the
-* reference.
-*/
-   if (block->state != IIO_BLOCK_STATE_DEAD) {
+   if (block->state != IIO_BLOCK_STATE_DEAD)
block->state = IIO_BLOCK_STATE_DONE;
-   list_add_tail(>head, >outgoing);
-   }
 }
 
 /**
@@ -261,7 +253,6 @@ static bool iio_dma_block_reusable(struct 
iio_dma_buffer_block *block)
 * not support abort and has not given back the block yet.
 */
switch (block->state) {
-   case IIO_BLOCK_STATE_DEQUEUED:
case IIO_BLOCK_STATE_QUEUED:
case IIO_BLOCK_STATE_DONE:
return true;
@@ -317,7 +308,6 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer)
 * dead. This means we can reset the lists without having to fear
 * corrution.
 */
-   INIT_LIST_HEAD(>outgoing);
spin_unlock_irq(>list_lock);
 
INIT_LIST_HEAD(>incoming);
@@ -456,14 +446,20 @@ static struct iio_dma_buffer_block 
*iio_dma_buffer_dequeue(
struct iio_dma_buffer_queue *queue)
 {
struct iio_dma_buffer_block *block;
+   unsigned int idx;
 
spin_lock_irq(>list_lock);
-   block = list_first_entry_or_null(>outgoing, struct
-   iio_dma_buffer_block, head);
-   if (block != NULL) {
-   list_del(>head);
-   block->state = IIO_BLOCK_STATE_DEQUEUED;
+
+   idx = queue->fileio.next_dequeue;
+   block = queue->fileio.blocks[idx];
+
+   if (block->state == IIO_BLOCK_STATE_DONE) {
+   idx = (idx + 1) % ARRAY_SIZE(queue->fileio.blocks);
+   queue->fileio.next_dequeue = idx;
+   } else {
+   block = NULL;
}
+
spin_unlock_irq(>list_lock);
 
return block;
@@ -539,6 +535,7 @@ size_t iio_dma_buffer_data_available(struct iio_buffer *buf)
struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buf);
struct iio_dma_buffer_block *block;
size_t data_available = 0;
+   unsigned int i;
 
/*
 * For counting the available bytes we'll use the size of the block not
@@ -552,8 +549,15 @@ size_t iio_dma_buffer_data_available(struct iio_buffer 
*buf)
data_available += queue->fileio.active_block->size;
 
spin_lock_irq(>list_lock);
-   list_for_each_entry(block, >outgoing, head)
-   data_available += block->size;
+
+   for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) {
+   block = queue->fileio.blocks[i];
+
+   if (block != queue->fileio.active_block
+   && block->state == IIO_BLOCK_STATE_DONE)
+   data_available += block->size;
+   }
+
spin_unlock_irq(>list_lock);
mutex_unlock(>lock);
 
@@ -617,7 +621,6 @@ int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue,
queue->ops = ops;
 
INIT_LIST_HEAD(>incoming);
-   INIT_LIST_HEAD(>outgoing);
 
mutex_init(>lock);
spin_lock_init(>list_lock);
@@ -645,7 +648,6 @@ void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue)
continue;
   

[PATCH v5 0/8] iio: new DMABUF based API, v5

2023-12-19 Thread Paul Cercueil
[V4 was: "iio: Add buffer write() support"][1]

Hi Jonathan,

This is a respin of the V3 of my patchset that introduced a new
interface based on DMABUF objects [2].

The V4 was a split of the patchset, to attempt to upstream buffer
write() support first. But since there is no current user upstream, it
was not merged. This V5 is about doing the opposite, and contains the
new DMABUF interface, without adding the buffer write() support. It can
already be used with the upstream adi-axi-adc driver.

In user-space, Libiio uses it to transfer back and forth blocks of
samples between the hardware and the applications, without having to
copy the data.

On a ZCU102 with a FMComms3 daughter board, running Libiio from the
pcercuei/dev-new-dmabuf-api branch [3], compiled with
WITH_LOCAL_DMABUF_API=OFF (so that it uses fileio):
  sudo utils/iio_rwdev -b 4096 -B cf-ad9361-lpc
  Throughput: 116 MiB/s

Same hardware, with the DMABUF API (WITH_LOCAL_DMABUF_API=ON):
  sudo utils/iio_rwdev -b 4096 -B cf-ad9361-lpc
  Throughput: 475 MiB/s

This benchmark only measures the speed at which the data can be fetched
to iio_rwdev's internal buffers, and does not actually try to read the
data (e.g. to pipe it to stdout). It shows that fetching the data is
more than 4x faster using the new interface.

When actually reading the data, the performance difference isn't that
impressive (maybe because in case of DMABUF the data is not in cache):

WITH_LOCAL_DMABUF_API=OFF (so that it uses fileio):
  sudo utils/iio_rwdev -b 4096 cf-ad9361-lpc | dd of=/dev/zero status=progress
  2446422528 bytes (2.4 GB, 2.3 GiB) copied, 22 s, 111 MB/s

WITH_LOCAL_DMABUF_API=ON:
  sudo utils/iio_rwdev -b 4096 cf-ad9361-lpc | dd of=/dev/zero status=progress
  2334388736 bytes (2.3 GB, 2.2 GiB) copied, 21 s, 114 MB/s

One interesting thing to note is that fileio is (currently) actually
faster than the DMABUF interface if you increase a lot the buffer size.
My explanation is that the cache invalidation routine takes more and
more time the bigger the DMABUF gets. This is because the DMABUF is
backed by small-size pages, so a (e.g.) 64 MiB DMABUF is backed by up
to 16 thousands pages, that have to be invalidated one by one. This can
be addressed by using huge pages, but the udmabuf driver does not (yet)
support creating DMABUFs backed by huge pages.

Anyway, the real benefits happen when the DMABUFs are either shared
between IIO devices, or between the IIO subsystem and another
filesystem. In that case, the DMABUFs are simply passed around drivers,
without the data being copied at any moment.

We use that feature to transfer samples from our transceivers to USB,
using a DMABUF interface to FunctionFS [4].

This drastically increases the throughput, to about 274 MiB/s over a
USB3 link, vs. 127 MiB/s using IIO's fileio interface + write() to the
FunctionFS endpoints, for a lower CPU usage (0.85 vs. 0.65 load avg.).

Based on linux-next/next-20231219.

Cheers,
-Paul

[1] https://lore.kernel.org/all/20230807112113.47157-1-p...@crapouillou.net/
[2] https://lore.kernel.org/all/20230403154800.215924-1-p...@crapouillou.net/
[3] https://github.com/analogdevicesinc/libiio/tree/pcercuei/dev-new-dmabuf-api
[4] https://lore.kernel.org/all/20230322092118.9213-1-p...@crapouillou.net/

---
Changelog:
- [3/8]: Replace V3's dmaengine_prep_slave_dma_array() with a new
  dmaengine_prep_slave_dma_vec(), which uses a new 'dma_vec' struct.
  Note that at some point we will need to support cyclic transfers
  using dmaengine_prep_slave_dma_vec(). Maybe with a new "flags"
  parameter to the function?

- [4/8]: Implement .device_prep_slave_dma_vec() instead of V3's
  .device_prep_slave_dma_array().

  @Vinod: this patch will cause a small conflict with my other
  patchset adding scatter-gather support to the axi-dmac driver.
  This patch adds a call to axi_dmac_alloc_desc(num_sgs), but the
  prototype of this function changed in my other patchset - it would
  have to be passed the "chan" variable. I don't know how you prefer it
  to be resolved. Worst case scenario (and if @Jonathan is okay with
  that) this one patch can be re-sent later, but it would make this
  patchset less "atomic".

- [5/8]:
  - Use dev_err() instead of pr_err()
  - Inline to_iio_dma_fence()
  - Add comment to explain why we unref twice when detaching dmabuf
  - Remove TODO comment. It is actually safe to free the file's
private data even when transfers are still pending because it
won't be accessed.
  - Fix documentation of new fields in struct iio_buffer_access_funcs
  - iio_dma_resv_lock() does not need to be exported, make it static

- [7/8]:
  - Use the new dmaengine_prep_slave_dma_vec().
  - Restrict to input buffers, since output buffers are not yet
supported by IIO buffers.

- [8/8]:
  Use description lists for the documentation of the three new IOCTLs
  instead of abusing subsections.

---
Alexandru Ardelean (1):
  iio: buffer-dma: split iio_dma_buffer_

Re: [PATCH RFC 01/10] dt-bindings: gpu: Add PowerVR Series5 SGX GPUs

2023-12-19 Thread Andrew Davis

On 12/18/23 4:54 AM, H. Nikolaus Schaller wrote:




Am 18.12.2023 um 11:14 schrieb Maxime Ripard :

On Mon, Dec 18, 2023 at 10:28:09AM +0100, H. Nikolaus Schaller wrote:

Hi Maxime,


Am 15.12.2023 um 14:33 schrieb Maxime Ripard :



It's for a separate architecture, with a separate driver, maintained out
of tree by a separate community, with a separate set of requirements as
evidenced by the other thread. And that's all fine in itself, but
there's very little reason to put these two bindings in the same file.

We could also turn this around, why is it important that it's in the
same file?


Same vendor. And enough similarity in architectures, even a logical sequence
of development of versions (SGX = Version 5, Rogue = Version 6+) behind.
(SGX and Rogue seem to be just trade names for their architecture development).


Again, none of that matters for *where* the binding is stored.


So what then speaks against extending the existing bindings file as proposed
here?


I mean, apart from everything you quoted, then sure, nothing speaks
against it.


AFAIK bindings should describe hardware and not communities or drivers
or who is currently maintaining it. The latter can change, the first not.


Bindings are supposed to describe hardware indeed. Nothing was ever said
about where those bindings are supposed to be located.

There's hundreds of other YAML bindings describing devices of the same
vendors and different devices from the same generation.


Usually SoC seem to be split over multiple files by subsystem. Not by versions
or generations. If the subsystems are similar enough they share the same 
bindings
doc instead of having one for each generation duplicating a lot of code.

Here is a comparable example that combines multiple vendors and generations:

Documentation/devicetree/bindings/usb/generic-ehci.yaml


EHCI is a single interface for USB2.0 controllers. It's a standard API,
and is made of a single driver that requires minor modifications to deal
with multiple devices.

We're very far from the same situation here.


How far are we really? And, it is the purpose of the driver to handle different 
cases.

That there are currently two drivers is just a matter of history and not a 
necessity.




If anything it'll make it easier for you. I'm really not sure why it is
controversial and you're fighting this so hard.


Well, you made it controversial by proposing to split what IMHO belongs 
together.


No, reviews aren't controversial.
The controversy started when you chose
to oppose it while you could have just rolled with it.


Well, you asked

"I think it would be best to have a separate file for this, img,sgx.yaml
maybe?"

and

"Because it's more convenient?"

I understood that as an invitation for discussing the pros and cons and working 
out the
most convenient solution. And that involves playing the devil's advocate which 
of course
is controversial by principle.

Now, IMHO all the pros and cons are on the table and the question is who makes 
a decision
how to go.



As much as I would land on the side of same file for both, the answer to this 
question
is simple: the maintainer makes the decision :) So I'll respin with separate 
binding files.

The hidden unaddressed issue here is that by making these bindings separate it 
implies
they are not on equal footing (i.e. pre-series6 GPUs are not true "powervr" and 
so do not
belong in img,powervr.yaml). So if no one objects I'd also like to do the 
rename of that
file as suggested before and have:

img,powervr-sgx.yaml
img,powervr-rogue.yaml




I feel that the original patch is good enough for its purpose and follows
some design pattern that can be deduced from other binding docs.


[citation needed]


Joke: Documentation/devicetree/bindings/* - I am not aware of a formal analysis 
of course.

But see my example for ehci. It follows the pattern I mean. If clocks, regs, 
interrupts,
resets, and more properties are (almost) the same, then group them and just 
differentiate
by different compatible strings. If necessary use some - if: clauses.

It is the task of drivers to handle the details.

As my other (maybe more important) comment to this patch did indicate we IMHO 
can easily
live with something like

+  - items:
+  - enum:
+  - ti,am62-gpu # IMG AXE GPU model/revision is fully discoverable
+  - ti,omap3430-gpu # sgx530 Rev 121
+  - ti,omap3630-gpu # sgx530 Rev 125
+  - ingenic,jz4780-gpu # sgx540 Rev 130
+  - ti,omap4430-gpu # sgx540 Rev 120
+  - allwinner,sun6i-a31-gpu # sgx544 MP2 Rev 115
+  - ti,omap4470-gpu # sgx544 MP1 Rev 112
+  - ti,omap5432-gpu # sgx544 MP2 Rev 105
+  - ti,am5728-gpu # sgx544 MP2 Rev 116
+  - ti,am6548-gpu # sgx544 MP1 Rev 117



While we could live with this, the "compatible" groupings makes life just a bit
easier. This is true really for any DT compatible string and is not based on
any 

Re: [PATCH 5/5] drm/panel: st7703: Drive XBD599 panel at higher clock rate

2023-12-19 Thread Jernej Škrabec
Dne ponedeljek, 18. december 2023 ob 14:35:23 CET je Frank Oltmanns napisal(a):
> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
> Acoording to it's datasheet, the SOC requires PLL-MIPI to run at more
> than 500 MHz.
> 
> Therefore, change [hv]sync_(start|end) so that we reach a clock rate
> that is high enough to drive PLL-MIPI within its limits.
> 
> Signed-off-by: Frank Oltmanns 

I'm not too sure about this patch. I see that PLL_MIPI doesn't have set
minimum frequency limit in clock driver. If you add it, clock framework
should find rate that is high enough and divisible with target rate.

Best regards,
Jernej  

> ---
>  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c 
> b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> index b55bafd1a8be..6886fd7f765e 100644
> --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> @@ -320,14 +320,14 @@ static int xbd599_init_sequence(struct st7703 *ctx)
>  
>  static const struct drm_display_mode xbd599_mode = {
>   .hdisplay= 720,
> - .hsync_start = 720 + 40,
> - .hsync_end   = 720 + 40 + 40,
> - .htotal  = 720 + 40 + 40 + 40,
> + .hsync_start = 720 + 65,
> + .hsync_end   = 720 + 65 + 65,
> + .htotal  = 720 + 65 + 65 + 65,
>   .vdisplay= 1440,
> - .vsync_start = 1440 + 18,
> - .vsync_end   = 1440 + 18 + 10,
> - .vtotal  = 1440 + 18 + 10 + 17,
> - .clock   = 69000,
> + .vsync_start = 1440 + 30,
> + .vsync_end   = 1440 + 30 + 22,
> + .vtotal  = 1440 + 30 + 22 + 29,
> + .clock   = (720 + 65 + 65 + 65) * (1440 + 30 + 22 + 29) * 60 / 1000,
>   .flags   = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
>   .width_mm= 68,
>   .height_mm   = 136,
> 
> 






[PATCH v3 28/29] ARM: dts: rockchip: Add HDMI node for RK3128

2023-12-19 Thread Alex Bee
RK3128 has Innosilicon based HDMI TX controller similar to the one found in
RK3036.
Add it and the respective port nodes to the SoC device tree.

Signed-off-by: Alex Bee 
---
changes in v2:
 - no changes

changes in v3:
 - no changes

 arch/arm/boot/dts/rockchip/rk3128.dtsi | 33 ++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/rockchip/rk3128.dtsi 
b/arch/arm/boot/dts/rockchip/rk3128.dtsi
index 1a3bc8b2bc6e..fb98873fd94e 100644
--- a/arch/arm/boot/dts/rockchip/rk3128.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3128.dtsi
@@ -270,6 +270,11 @@ vop: vop@1010e000 {
vop_out: port {
#address-cells = <1>;
#size-cells = <0>;
+
+   vop_out_hdmi: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <_in_vop>;
+   };
};
};
 
@@ -463,6 +468,34 @@ usb2phy_otg: otg-port {
};
};
 
+   hdmi: hdmi@20034000 {
+   compatible = "rockchip,rk3128-inno-hdmi";
+   reg = <0x20034000 0x4000>;
+   interrupts = ;
+   clocks = < PCLK_HDMI>, < DCLK_VOP>;
+   clock-names = "pclk", "ref";
+   pinctrl-names = "default";
+   pinctrl-0 = <_xfer _hpd _cec>;
+   power-domains = < RK3128_PD_VIO>;
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   hdmi_in: port@0 {
+   reg = <0>;
+   hdmi_in_vop: endpoint {
+   remote-endpoint = <_out_hdmi>;
+   };
+   };
+
+   hdmi_out: port@1 {
+   reg = <1>;
+   };
+   };
+   };
+
timer0: timer@20044000 {
compatible = "rockchip,rk3128-timer", "rockchip,rk3288-timer";
reg = <0x20044000 0x20>;
-- 
2.43.0



[PATCH v3 27/29] ARM: dts: rockchip: Add display subsystem for RK3128

2023-12-19 Thread Alex Bee
Add vop and display-subsystem nodes to RK3128's device tree.

Signed-off-by: Alex Bee 
---
changes in v2:
 - no changes

changes in v3:
 - no changes

 arch/arm/boot/dts/rockchip/rk3128.dtsi | 27 ++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm/boot/dts/rockchip/rk3128.dtsi 
b/arch/arm/boot/dts/rockchip/rk3128.dtsi
index e2264c40b924..1a3bc8b2bc6e 100644
--- a/arch/arm/boot/dts/rockchip/rk3128.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3128.dtsi
@@ -115,6 +115,12 @@ opp-12 {
};
};
 
+   display_subsystem: display-subsystem {
+   compatible = "rockchip,display-subsystem";
+   ports = <_out>;
+   status = "disabled";
+   };
+
gpu_opp_table: opp-table-1 {
compatible = "operating-points-v2";
 
@@ -246,6 +252,27 @@ power-domain@RK3128_PD_GPU {
};
};
 
+   vop: vop@1010e000 {
+   compatible = "rockchip,rk3126-vop";
+   reg = <0x1010e000 0x300>;
+   interrupts = ;
+   clocks = < ACLK_LCDC0>, < DCLK_VOP>,
+< HCLK_LCDC0>;
+   clock-names = "aclk_vop", "dclk_vop",
+ "hclk_vop";
+   resets = < SRST_VOP_A>, < SRST_VOP_H>,
+< SRST_VOP_D>;
+   reset-names = "axi", "ahb",
+ "dclk";
+   power-domains = < RK3128_PD_VIO>;
+   status = "disabled";
+
+   vop_out: port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+   };
+
qos_gpu: qos@1012d000 {
compatible = "rockchip,rk3128-qos", "syscon";
reg = <0x1012d000 0x20>;
-- 
2.43.0



[PATCH v3 24/29] drm/rockchip: inno_hdmi: Add RK3128 support

2023-12-19 Thread Alex Bee
This variant requires the phy reference clock to be enabled before the DDC
block can work and the (initial) DDC bus frequency is calculated based on
the rate of this clock. Besides the only difference is phy configuration
required to make the driver working for this variant as well.

Signed-off-by: Alex Bee 
---
changes in v2:
 - no changes

changes in v3:
 - no changes

 drivers/gpu/drm/rockchip/inno_hdmi.c | 46 +---
 1 file changed, 41 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index df979bab9abd..8a1a2320749a 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -51,6 +51,7 @@ struct inno_hdmi {
struct device *dev;
 
struct clk *pclk;
+   struct clk *refclk;
void __iomem *regs;
 
struct drm_connectorconnector;
@@ -132,6 +133,12 @@ static struct inno_hdmi_phy_config 
rk3036_hdmi_phy_configs[] = {
{  ~0UL, 0x00, 0x00 }
 };
 
+static struct inno_hdmi_phy_config rk3128_hdmi_phy_configs[] = {
+   {  7425, 0x3f, 0xaa },
+   { 16500, 0x5f, 0xaa },
+   {  ~0UL, 0x00, 0x00 }
+};
+
 static int inno_hdmi_find_phy_config(struct inno_hdmi *hdmi,
 unsigned long pixelclk)
 {
@@ -905,6 +912,20 @@ static int inno_hdmi_bind(struct device *dev, struct 
device *master,
return ret;
}
 
+   hdmi->refclk = devm_clk_get_optional(hdmi->dev, "ref");
+   if (IS_ERR(hdmi->refclk)) {
+   DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI reference 
clock\n");
+   ret = PTR_ERR(hdmi->refclk);
+   goto err_disable_pclk;
+   }
+
+   ret = clk_prepare_enable(hdmi->refclk);
+   if (ret) {
+   DRM_DEV_ERROR(hdmi->dev,
+ "Cannot enable HDMI reference clock: %d\n", ret);
+   goto err_disable_pclk;
+   }
+
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
@@ -921,12 +942,16 @@ static int inno_hdmi_bind(struct device *dev, struct 
device *master,
}
 
/*
-* When IP controller haven't configured to an accurate video
-* timing, then the TMDS clock source would be switched to
-* PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
-* and reconfigure the DDC clock.
+* When the controller isn't configured to an accurate
+* video timing and there is no reference clock available,
+* then the TMDS clock source would be switched to PCLK_HDMI,
+* so we need to init the TMDS rate to PCLK rate, and
+* reconfigure the DDC clock.
 */
-   inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->pclk));
+   if (hdmi->refclk)
+   inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->refclk));
+   else
+   inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->pclk));
 
ret = inno_hdmi_register(drm, hdmi);
if (ret)
@@ -950,6 +975,8 @@ static int inno_hdmi_bind(struct device *dev, struct device 
*master,
 err_put_adapter:
i2c_put_adapter(hdmi->ddc);
 err_disable_clk:
+   clk_disable_unprepare(hdmi->refclk);
+err_disable_pclk:
clk_disable_unprepare(hdmi->pclk);
return ret;
 }
@@ -963,6 +990,7 @@ static void inno_hdmi_unbind(struct device *dev, struct 
device *master,
hdmi->encoder.encoder.funcs->destroy(>encoder.encoder);
 
i2c_put_adapter(hdmi->ddc);
+   clk_disable_unprepare(hdmi->refclk);
clk_disable_unprepare(hdmi->pclk);
 }
 
@@ -986,10 +1014,18 @@ static const struct inno_hdmi_variant 
rk3036_inno_hdmi_variant = {
.default_phy_config = _hdmi_phy_configs[1],
 };
 
+static const struct inno_hdmi_variant rk3128_inno_hdmi_variant = {
+   .phy_configs = rk3128_hdmi_phy_configs,
+   .default_phy_config = _hdmi_phy_configs[1],
+};
+
 static const struct of_device_id inno_hdmi_dt_ids[] = {
{ .compatible = "rockchip,rk3036-inno-hdmi",
  .data = _inno_hdmi_variant,
},
+   { .compatible = "rockchip,rk3128-inno-hdmi",
+ .data = _inno_hdmi_variant,
+   },
{},
 };
 MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
-- 
2.43.0



[PATCH v3 16/29] drm/rockchip: inno_hdmi: Remove unused drm device pointer

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

The drm_dev field in the inno_hdmi struct stores a pointer to the DRM
device but is never used anywhere in the driver. Let's remove it.

Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - added my SoB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 49367ca24125..51c1a69dfcc0 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -44,7 +44,6 @@ struct inno_hdmi_i2c {
 
 struct inno_hdmi {
struct device *dev;
-   struct drm_device *drm_dev;
 
int irq;
struct clk *pclk;
@@ -757,7 +756,6 @@ static int inno_hdmi_bind(struct device *dev, struct device 
*master,
return -ENOMEM;
 
hdmi->dev = dev;
-   hdmi->drm_dev = drm;
 
hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(hdmi->regs))
-- 
2.43.0



[PATCH v3 14/29] drm/rockchip: inno_hdmi: Move infoframe disable to separate function

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

The code to upload infoframes to the controller uses a weird construct
which, based on the previous function call return code, will either
disable or enable that infoframe.

In order to get rid of that argument, let's split the function to
disable the infoframe into a separate function and make it obvious what
we are doing in the error path.

Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - added my SoB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 46 ++--
 1 file changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 5c9f1325441f..10466c2aa520 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -205,34 +205,44 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
inno_hdmi_set_pwr_mode(hdmi, NORMAL);
 }
 
-static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
- union hdmi_infoframe *frame, u32 frame_index)
+static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi, u32 frame_index)
 {
struct drm_connector *connector = >connector;
 
if (frame_index != INFOFRAME_AVI) {
drm_err(connector->dev,
"Unsupported infoframe type: %u\n", frame_index);
-   return 0;
+   return;
}
 
hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
+}
 
-   if (setup_rc >= 0) {
-   u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
-   ssize_t rc, i;
-
-   rc = hdmi_infoframe_pack(frame, packed_frame,
-sizeof(packed_frame));
-   if (rc < 0)
-   return rc;
+static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
+ union hdmi_infoframe *frame, u32 frame_index)
+{
+   struct drm_connector *connector = >connector;
+   u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
+   ssize_t rc, i;
 
-   for (i = 0; i < rc; i++)
-   hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
-   packed_frame[i]);
+   if (frame_index != INFOFRAME_AVI) {
+   drm_err(connector->dev,
+   "Unsupported infoframe type: %u\n", frame_index);
+   return 0;
}
 
-   return setup_rc;
+   inno_hdmi_disable_frame(hdmi, frame_index);
+
+   rc = hdmi_infoframe_pack(frame, packed_frame,
+sizeof(packed_frame));
+   if (rc < 0)
+   return rc;
+
+   for (i = 0; i < rc; i++)
+   hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
+   packed_frame[i]);
+
+   return 0;
 }
 
 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
@@ -244,6 +254,10 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi 
*hdmi,
rc = drm_hdmi_avi_infoframe_from_display_mode(,
  >connector,
  mode);
+   if (rc) {
+   inno_hdmi_disable_frame(hdmi, INFOFRAME_AVI);
+   return rc;
+   }
 
if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
@@ -252,7 +266,7 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi 
*hdmi,
else
frame.avi.colorspace = HDMI_COLORSPACE_RGB;
 
-   return inno_hdmi_upload_frame(hdmi, rc, , INFOFRAME_AVI);
+   return inno_hdmi_upload_frame(hdmi, , INFOFRAME_AVI);
 }
 
 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
-- 
2.43.0



[PATCH v3 21/29] drm/rockchip: inno_hdmi: Don't power up the phy after resetting

2023-12-19 Thread Alex Bee
inno_hdmi_reset is only ever called when initializing the controller. At
this point it’s completely uneccessary to power up the PHY, since all
what has to work at this point is the DDC bus. The phy will be powered up
correctly when a mode is set in inno_hdmi_encoder_enable and disabled in
inno_hdmi_encoder_disable.
Set it to LOWER_PWR after resetting the controller.

Signed-off-by: Alex Bee 
---
changes in v3:
 - new patch

 drivers/gpu/drm/rockchip/inno_hdmi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index e6d37772500c..9fea464b6234 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -202,7 +202,7 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
 
-   inno_hdmi_set_pwr_mode(hdmi, NORMAL);
+   inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
 }
 
 static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
-- 
2.43.0



[PATCH v3 26/29] drm/rockchip: inno_hdmi: Drop custom fill_modes hook

2023-12-19 Thread Alex Bee
Now that we have proper pixelclock-based mode validation we can drop the
custom fill_modes hook.
CRTC size validation for the display controller has been added with
Commit 8e140cb60270 ("drm/rockchip: vop: limit maximum resolution to
hardware capabilities")

Signed-off-by: Alex Bee 
Reviewed-by: Maxime Ripard 
---
changes in v2:
 - no changes

changes in v3:
 - collect RB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index a2a9e54b76c0..29a2c1b87294 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -631,13 +631,6 @@ inno_hdmi_connector_mode_valid(struct drm_connector 
*connector,
return  inno_hdmi_display_mode_valid(hdmi, mode);
 }
 
-static int
-inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
-  uint32_t maxX, uint32_t maxY)
-{
-   return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
-}
-
 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
 {
drm_connector_unregister(connector);
@@ -691,7 +684,7 @@ inno_hdmi_atomic_destroy_state(struct drm_connector 
*connector,
 }
 
 static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
-   .fill_modes = inno_hdmi_probe_single_connector_modes,
+   .fill_modes = drm_helper_probe_single_connector_modes,
.detect = inno_hdmi_connector_detect,
.destroy = inno_hdmi_connector_destroy,
.reset = inno_hdmi_connector_reset,
-- 
2.43.0



[PATCH v3 07/29] drm/rockchip: inno_hdmi: Get rid of mode_set

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

We're not doing anything special in atomic_mode_set so we can simply
merge it into atomic_enable.

Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - added my SoB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 48c4f010b260..299770e481b7 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -490,21 +490,22 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
return 0;
 }
 
-static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
-  struct drm_crtc_state *crtc_state,
-  struct drm_connector_state *conn_state)
-{
-   struct drm_display_mode *adj_mode = _state->adjusted_mode;
-   struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
-
-   inno_hdmi_setup(hdmi, adj_mode);
-}
-
 static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
 struct drm_atomic_state *state)
 {
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
+   struct drm_connector_state *conn_state;
+   struct drm_crtc_state *crtc_state;
+
+   conn_state = drm_atomic_get_new_connector_state(state, 
>connector);
+   if (WARN_ON(!conn_state))
+   return;
+
+   crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+   if (WARN_ON(!crtc_state))
+   return;
 
+   inno_hdmi_setup(hdmi, _state->adjusted_mode);
inno_hdmi_set_pwr_mode(hdmi, NORMAL);
 }
 
@@ -533,7 +534,6 @@ static struct drm_encoder_helper_funcs 
inno_hdmi_encoder_helper_funcs = {
.atomic_check   = inno_hdmi_encoder_atomic_check,
.atomic_enable  = inno_hdmi_encoder_enable,
.atomic_disable = inno_hdmi_encoder_disable,
-   .atomic_mode_set= inno_hdmi_encoder_mode_set,
 };
 
 static enum drm_connector_status
-- 
2.43.0



[PATCH v3 29/29] ARM: dts: rockchip: Enable HDMI output for XPI-3128

2023-12-19 Thread Alex Bee
Add an hdmi-connector node and enable the hdmi, display-subsystem and vop
nodes.

Signed-off-by: Alex Bee 
---
changes in v2:
 - no changes

changes in v3:
 - no changes

 .../arm/boot/dts/rockchip/rk3128-xpi-3128.dts | 29 +++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts 
b/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts
index 03a97881519a..21c1678f4e91 100644
--- a/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts
+++ b/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts
@@ -47,6 +47,17 @@ dc_5v: dc-5v-regulator {
regulator-boot-on;
};
 
+   hdmi-connnector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_connector_in: endpoint {
+   remote-endpoint = <_connector_out>;
+   };
+   };
+   };
+
/*
 * This is a vbus-supply, which also supplies the GL852G usb hub,
 * thus has to be always-on
@@ -239,6 +250,10 @@  {
cpu-supply = <_arm>;
 };
 
+_subsystem {
+   status = "okay";
+};
+
  {
bus-width = <8>;
vmmc-supply = <_io>;
@@ -328,6 +343,16 @@  {
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_connector_out: endpoint {
+   remote-endpoint = <_connector_in>;
+   };
+};
+
  {
phy0: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
@@ -423,3 +448,7 @@ _host {
 _otg {
status = "okay";
 };
+
+ {
+   status = "okay";
+};
-- 
2.43.0



[PATCH v3 10/29] drm/rockchip: inno_hdmi: Remove useless input format

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

The driver has a lot of logic to deal with multiple input formats, but
hardcodes it to RGB. This means that most of that code has been dead
code, so let's get rid of it.

Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
[made checkpatch happy]
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - none

 drivers/gpu/drm/rockchip/inno_hdmi.c | 41 
 1 file changed, 11 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 58aff7a9c09a..7c75feedacad 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -28,7 +28,6 @@
 #include "inno_hdmi.h"
 
 struct hdmi_data_info {
-   unsigned int enc_in_format;
unsigned int enc_out_format;
unsigned int colorimetry;
 };
@@ -328,47 +327,30 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi 
*hdmi)
v_VIDEO_INPUT_CSP(0);
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
 
-   if (data->enc_in_format == data->enc_out_format) {
-   if ((data->enc_in_format == HDMI_COLORSPACE_RGB) ||
-   (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) {
-   value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
-   hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
-
-   hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
- m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
- v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
- v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
-   return 0;
-   }
+   if (data->enc_out_format == HDMI_COLORSPACE_RGB) {
+   value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
+   hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
+
+   hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
+ m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
+ v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
+ v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
+   return 0;
}
 
if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
-   if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
-   (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
+   if (data->enc_out_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
csc_enable = v_CSC_ENABLE;
-   } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
-  (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
-   csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
-   auto_csc = AUTO_CSC_ENABLE;
-   c0_c2_change = C0_C2_CHANGE_DISABLE;
-   csc_enable = v_CSC_DISABLE;
}
} else {
-   if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
-   (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
+   if (data->enc_out_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
csc_enable = v_CSC_ENABLE;
-   } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
-  (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
-   csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
-   auto_csc = AUTO_CSC_ENABLE;
-   c0_c2_change = C0_C2_CHANGE_DISABLE;
-   csc_enable = v_CSC_DISABLE;
}
}
 
@@ -443,7 +425,6 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
struct drm_display_info *display = >connector.display_info;
u8 vic = drm_match_cea_mode(mode);
 
-   hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB;
hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
 
if (vic == 6 || vic == 7 ||
-- 
2.43.0



[PATCH v3 19/29] drm/rockchip: inno_hdmi: Subclass connector state

2023-12-19 Thread Alex Bee
The data which is currently hold in hdmi_data should not be part of device
itself but of the connector state.
Introduce a connector state subclass and move the data from hdmi_data in
there.

Suggested-by: Maxime Ripard 
Signed-off-by: Alex Bee 
---
changes in v2:
 - new patch

changes in v3:
 - added missing customizations of reset and atomic_destroy_state connector 
hooks
 - moved inno_conn_state member assignments to atomic_check

 drivers/gpu/drm/rockchip/inno_hdmi.c | 111 ---
 1 file changed, 84 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index c306db90832a..7ce5836fc80d 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -26,11 +26,6 @@
 
 #include "inno_hdmi.h"
 
-struct hdmi_data_info {
-   unsigned int enc_out_format;
-   unsigned int colorimetry;
-};
-
 struct inno_hdmi_i2c {
struct i2c_adapter adap;
 
@@ -52,8 +47,12 @@ struct inno_hdmi {
 
struct inno_hdmi_i2c *i2c;
struct i2c_adapter *ddc;
+};
 
-   struct hdmi_data_info   hdmi_data;
+struct inno_hdmi_connector_state {
+   struct drm_connector_state  base;
+   unsigned intenc_out_format;
+   unsigned intcolorimetry;
 };
 
 static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
@@ -68,6 +67,9 @@ static struct inno_hdmi *connector_to_inno_hdmi(struct 
drm_connector *connector)
return container_of(connector, struct inno_hdmi, connector);
 }
 
+#define to_inno_hdmi_conn_state(conn_state) \
+   container_of_const(conn_state, struct inno_hdmi_connector_state, base)
+
 enum {
CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
@@ -246,6 +248,10 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
  struct drm_display_mode *mode)
 {
+   struct drm_connector *connector = >connector;
+   struct drm_connector_state *conn_state = connector->state;
+   struct inno_hdmi_connector_state *inno_conn_state =
+   to_inno_hdmi_conn_state(conn_state);
union hdmi_infoframe frame;
int rc;
 
@@ -257,9 +263,9 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi 
*hdmi,
return rc;
}
 
-   if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
+   if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444)
frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
-   else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
+   else if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV422)
frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
else
frame.avi.colorspace = HDMI_COLORSPACE_RGB;
@@ -269,7 +275,10 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi 
*hdmi,
 
 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
 {
-   struct hdmi_data_info *data = >hdmi_data;
+   struct drm_connector *connector = >connector;
+   struct drm_connector_state *conn_state = connector->state;
+   struct inno_hdmi_connector_state *inno_conn_state =
+   to_inno_hdmi_conn_state(conn_state);
int c0_c2_change = 0;
int csc_enable = 0;
int csc_mode = 0;
@@ -287,7 +296,7 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi 
*hdmi)
v_VIDEO_INPUT_CSP(0);
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
 
-   if (data->enc_out_format == HDMI_COLORSPACE_RGB) {
+   if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
 
@@ -298,15 +307,15 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi 
*hdmi)
return 0;
}
 
-   if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
-   if (data->enc_out_format == HDMI_COLORSPACE_YUV444) {
+   if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
+   if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
csc_enable = v_CSC_ENABLE;
}
} else {
-   if (data->enc_out_format == HDMI_COLORSPACE_YUV444) {
+   if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
@@ -383,17 +392,6 @@ static int 

[PATCH v3 05/29] drm/rockchip: inno_hdmi: Remove useless copy of drm_display_mode

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

The driver maintains a copy of the adjusted mode but doesn't use it
anywhere. Remove it.

Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - added my SoB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 0b1740b38c7b..14d2ba92a606 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -62,7 +62,6 @@ struct inno_hdmi {
unsigned int tmds_rate;
 
struct hdmi_data_info   hdmi_data;
-   struct drm_display_mode previous_mode;
 };
 
 static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
@@ -498,9 +497,6 @@ static void inno_hdmi_encoder_mode_set(struct drm_encoder 
*encoder,
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
 
inno_hdmi_setup(hdmi, adj_mode);
-
-   /* Store the display mode for plugin/DPMS poweron events */
-   drm_mode_copy(>previous_mode, adj_mode);
 }
 
 static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
-- 
2.43.0



[PATCH v3 20/29] drm/rockchip: inno_hdmi: Correctly setup HDMI quantization range

2023-12-19 Thread Alex Bee
The display controller will always give full range RGB regardless of the
mode set, but HDMI requires certain modes to be transmitted in limited
range RGB. This is especially required for HDMI sinks which do not support
non-standard quantization ranges.

This enables color space conversion for those modes and sets the
quantization range accordingly in the AVI infoframe.

Signed-off-by: Alex Bee 
---
changes in v2:
 - made rgb_limited_range part of the new custom connector state

changes in v3:
 - moved assignment of rgb_limited_range to atomic check

 drivers/gpu/drm/rockchip/inno_hdmi.c | 60 +++-
 1 file changed, 42 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 7ce5836fc80d..e6d37772500c 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -53,6 +53,7 @@ struct inno_hdmi_connector_state {
struct drm_connector_state  base;
unsigned intenc_out_format;
unsigned intcolorimetry;
+   boolrgb_limited_range;
 };
 
 static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
@@ -270,6 +271,18 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi 
*hdmi,
else
frame.avi.colorspace = HDMI_COLORSPACE_RGB;
 
+   if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
+   drm_hdmi_avi_infoframe_quant_range(,
+  connector, mode,
+  
inno_conn_state->rgb_limited_range ?
+  
HDMI_QUANTIZATION_RANGE_LIMITED :
+  
HDMI_QUANTIZATION_RANGE_FULL);
+   } else {
+   frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
+   frame.avi.ycc_quantization_range =
+   HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
+   }
+
return inno_hdmi_upload_frame(hdmi, , HDMI_INFOFRAME_TYPE_AVI);
 }
 
@@ -297,29 +310,37 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi 
*hdmi)
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
 
if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
-   value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
-   hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
-
-   hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
- m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
- v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
- v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
-   return 0;
-   }
-
-   if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
-   if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
-   csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
+   if (inno_conn_state->rgb_limited_range) {
+   csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
csc_enable = v_CSC_ENABLE;
+
+   } else {
+   value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
+   hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
+
+   hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
+ m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
+ v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
+ v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
+   return 0;
}
} else {
-   if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
-   csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
-   auto_csc = AUTO_CSC_DISABLE;
-   c0_c2_change = C0_C2_CHANGE_DISABLE;
-   csc_enable = v_CSC_ENABLE;
+   if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
+   if (inno_conn_state->enc_out_format == 
HDMI_COLORSPACE_YUV444) {
+   csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
+   auto_csc = AUTO_CSC_DISABLE;
+   c0_c2_change = C0_C2_CHANGE_DISABLE;
+   csc_enable = v_CSC_ENABLE;
+   }
+   } else {
+   if (inno_conn_state->enc_out_format == 
HDMI_COLORSPACE_YUV444) {
+   csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
+   auto_csc = AUTO_CSC_DISABLE;
+   c0_c2_change = C0_C2_CHANGE_DISABLE;
+   csc_enable = v_CSC_ENABLE;
+  

[PATCH v3 25/29] drm/rockchip: inno_hdmi: Add basic mode validation

2023-12-19 Thread Alex Bee
As per TRM this controller supports pixelclocks starting from 25 MHz. The
maximum supported pixelclocks are defined by the phy configurations we
have. Also it can't support modes that require doubled clocks. If the
variant has a phy reference clock we can additionally validate against VESA
DMT'srecommendations.

Signed-off-by: Alex Bee 
Reviewed-by: Maxime Ripard 
---
changes in v2:
 - rename inno_mode_valid -> inno_hdmi_display_mode_valid
 - fixed max_tolerance calculation
 - use abs_diff() instead of abs()
 - call in inno_hdmi_display_mode_valid in atomic_check

changes in v3:
 - collect RB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 42 ++--
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 8a1a2320749a..a2a9e54b76c0 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -26,6 +26,8 @@
 
 #include "inno_hdmi.h"
 
+#define INNO_HDMI_MIN_TMDS_CLOCK  2500U
+
 struct inno_hdmi_phy_config {
unsigned long pixelclock;
u8 pre_emphasis;
@@ -497,6 +499,38 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
return 0;
 }
 
+static enum drm_mode_status inno_hdmi_display_mode_valid(struct inno_hdmi 
*hdmi,
+struct 
drm_display_mode *mode)
+{
+   unsigned long mpixelclk, max_tolerance;
+   long rounded_refclk;
+
+   /* No support for double-clock modes */
+   if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+   return MODE_BAD;
+
+   mpixelclk = mode->clock * 1000;
+
+   if (mpixelclk < INNO_HDMI_MIN_TMDS_CLOCK)
+   return MODE_CLOCK_LOW;
+
+   if (inno_hdmi_find_phy_config(hdmi, mpixelclk) < 0)
+   return MODE_CLOCK_HIGH;
+
+   if (hdmi->refclk) {
+   rounded_refclk = clk_round_rate(hdmi->refclk, mpixelclk);
+   if (rounded_refclk < 0)
+   return MODE_BAD;
+
+   /* Vesa DMT standard mentions +/- 0.5% max tolerance */
+   max_tolerance = mpixelclk / 200;
+   if (abs_diff((unsigned long)rounded_refclk, mpixelclk) > 
max_tolerance)
+   return MODE_NOCLOCK;
+   }
+
+   return MODE_OK;
+}
+
 static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
 struct drm_atomic_state *state)
 {
@@ -529,6 +563,7 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
   struct drm_connector_state *conn_state)
 {
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+   struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
struct drm_display_mode *mode = _state->adjusted_mode;
u8 vic = drm_match_cea_mode(mode);
struct inno_hdmi_connector_state *inno_conn_state =
@@ -549,7 +584,8 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
inno_conn_state->rgb_limited_range =
drm_default_rgb_quant_range(mode) == 
HDMI_QUANTIZATION_RANGE_LIMITED;
 
-   return 0;
+   return  inno_hdmi_display_mode_valid(hdmi,
+   _state->adjusted_mode) == MODE_OK ? 0 : 
-EINVAL;
 }
 
 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
@@ -590,7 +626,9 @@ static enum drm_mode_status
 inno_hdmi_connector_mode_valid(struct drm_connector *connector,
   struct drm_display_mode *mode)
 {
-   return MODE_OK;
+   struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
+
+   return  inno_hdmi_display_mode_valid(hdmi, mode);
 }
 
 static int
-- 
2.43.0



[PATCH v3 17/29] drm/rockchip: inno_hdmi: Drop irq struct member

2023-12-19 Thread Alex Bee
The struct member irq isn't used anywhere. Drop it.

Signed-off-by: Alex Bee 
Reviewed-by: Maxime Ripard 
---
changes in v2:
 - new patch

changes in v3:
 - collect RB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 51c1a69dfcc0..138cd4287dea 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -45,7 +45,6 @@ struct inno_hdmi_i2c {
 struct inno_hdmi {
struct device *dev;
 
-   int irq;
struct clk *pclk;
void __iomem *regs;
 
-- 
2.43.0



[PATCH v3 04/29] drm/rockchip: inno_hdmi: Remove useless mode_fixup

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

The mode_fixup implementation doesn't do anything, so we can simply
remove it.

Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - added my SoB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 345253e033c5..0b1740b38c7b 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -517,13 +517,6 @@ static void inno_hdmi_encoder_disable(struct drm_encoder 
*encoder)
inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
 }
 
-static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
-const struct drm_display_mode *mode,
-struct drm_display_mode *adj_mode)
-{
-   return true;
-}
-
 static int
 inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
   struct drm_crtc_state *crtc_state,
@@ -540,7 +533,6 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
.enable = inno_hdmi_encoder_enable,
.disable= inno_hdmi_encoder_disable,
-   .mode_fixup = inno_hdmi_encoder_mode_fixup,
.mode_set   = inno_hdmi_encoder_mode_set,
.atomic_check = inno_hdmi_encoder_atomic_check,
 };
-- 
2.43.0



[PATCH v3 18/29] drm/rockchip: inno_hdmi: Remove useless include

2023-12-19 Thread Alex Bee
The inclusion syscon.h isn't used anywhere. Remove it.

Signed-off-by: Alex Bee 
Reviewed-by: Maxime Ripard 
---
changes in v2:
 - new patch

changes in v3:
 - collect RB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 138cd4287dea..c306db90832a 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -10,7 +10,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-- 
2.43.0



[PATCH v3 08/29] drm/rockchip: inno_hdmi: no need to store vic

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

The mode's VIC is only ever used in the inno_hdmi_setup() function so
there's no need to store it in the main structure.

Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
[made checkpatch happy]
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - none

 drivers/gpu/drm/rockchip/inno_hdmi.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 299770e481b7..d99896f1a73a 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -28,7 +28,6 @@
 #include "inno_hdmi.h"
 
 struct hdmi_data_info {
-   int vic;
bool sink_has_audio;
unsigned int enc_in_format;
unsigned int enc_out_format;
@@ -443,16 +442,15 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
   struct drm_display_mode *mode)
 {
struct drm_display_info *display = >connector.display_info;
-
-   hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
+   u8 vic = drm_match_cea_mode(mode);
 
hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB;
hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
 
-   if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) ||
-   (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) ||
-   (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) ||
-   (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18))
+   if (vic == 6 || vic == 7 ||
+   vic == 21 || vic == 22 ||
+   vic == 2 || vic == 3 ||
+   vic == 17 || vic == 18)
hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
else
hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
-- 
2.43.0



[PATCH v3 22/29] drm/rockchip: inno_hdmi: Split power mode setting

2023-12-19 Thread Alex Bee
This splits setting the power mode of the controller / phy in two
functions. It's done in preparation of setting up the phy based on the
pixelclock.

No functional changes intended.

Signed-off-by: Alex Bee 
---
changes in v3:
 - new patch

 drivers/gpu/drm/rockchip/inno_hdmi.c | 54 +---
 drivers/gpu/drm/rockchip/inno_hdmi.h |  5 ---
 2 files changed, 24 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 9fea464b6234..e21f6d7aeee6 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -154,38 +154,31 @@ static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, 
bool enable)
hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF);
 }
 
-static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
+static void inno_hdmi_standby(struct inno_hdmi *hdmi)
 {
-   switch (mode) {
-   case NORMAL:
-   inno_hdmi_sys_power(hdmi, false);
+   inno_hdmi_sys_power(hdmi, false);
 
-   hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
-   hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
-
-   hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
-   hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
-   hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
-   hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f);
-   hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00);
-   hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01);
-
-   inno_hdmi_sys_power(hdmi, true);
-   break;
+   hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00);
+   hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00);
+   hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00);
+   hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
+};
 
-   case LOWER_PWR:
-   inno_hdmi_sys_power(hdmi, false);
-   hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00);
-   hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00);
-   hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00);
-   hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
+static void inno_hdmi_power_up(struct inno_hdmi *hdmi)
+{
+   inno_hdmi_sys_power(hdmi, false);
 
-   break;
+   hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
+   hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
+   hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
+   hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
+   hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
+   hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f);
+   hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00);
+   hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01);
 
-   default:
-   DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode);
-   }
-}
+   inno_hdmi_sys_power(hdmi, true);
+};
 
 static void inno_hdmi_reset(struct inno_hdmi *hdmi)
 {
@@ -202,7 +195,7 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
 
-   inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
+   inno_hdmi_standby(hdmi);
 }
 
 static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
@@ -441,6 +434,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
  v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
 
+   inno_hdmi_power_up(hdmi);
+
return 0;
 }
 
@@ -460,7 +455,6 @@ static void inno_hdmi_encoder_enable(struct drm_encoder 
*encoder,
return;
 
inno_hdmi_setup(hdmi, _state->adjusted_mode);
-   inno_hdmi_set_pwr_mode(hdmi, NORMAL);
 }
 
 static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
@@ -468,7 +462,7 @@ static void inno_hdmi_encoder_disable(struct drm_encoder 
*encoder,
 {
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
 
-   inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
+   inno_hdmi_standby(hdmi);
 }
 
 static int
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.h 
b/drivers/gpu/drm/rockchip/inno_hdmi.h
index 93245b55f967..a7edf3559e60 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.h
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.h
@@ -10,11 +10,6 @@
 
 #define DDC_SEGMENT_ADDR   0x30
 
-enum PWR_MODE {
-   NORMAL,
-   LOWER_PWR,
-};
-
 #define HDMI_SCL_RATE  (100*1000)
 #define DDC_BUS_FREQ_L 0x4b
 #define DDC_BUS_FREQ_H 0x4c
-- 
2.43.0



[PATCH v3 23/29] drm/rockchip: inno_hdmi: Add variant support

2023-12-19 Thread Alex Bee
In preparation to support RK3128's integration of the controller, this
patch adds a simple variant implementation. They mainly differ in the phy
configuration required, so those are part of the match_data. The values
have been taken from downstream. The pixelclocks in there are meant to be
max-inclusive.

Signed-off-by: Alex Bee 
---
changes in v2:
 - no changes

changes in v3:
 - adapt to the newly introduced inno_hdmi_power_up / inno_hdmi_standby 
functions

 drivers/gpu/drm/rockchip/inno_hdmi.c | 74 ++--
 1 file changed, 69 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index e21f6d7aeee6..df979bab9abd 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -26,6 +26,17 @@
 
 #include "inno_hdmi.h"
 
+struct inno_hdmi_phy_config {
+   unsigned long pixelclock;
+   u8 pre_emphasis;
+   u8 voltage_level_control;
+};
+
+struct inno_hdmi_variant {
+   struct inno_hdmi_phy_config *phy_configs;
+   struct inno_hdmi_phy_config *default_phy_config;
+};
+
 struct inno_hdmi_i2c {
struct i2c_adapter adap;
 
@@ -47,6 +58,8 @@ struct inno_hdmi {
 
struct inno_hdmi_i2c *i2c;
struct i2c_adapter *ddc;
+
+   const struct inno_hdmi_variant *variant;
 };
 
 struct inno_hdmi_connector_state {
@@ -113,6 +126,30 @@ static const char coeff_csc[][24] = {
},
 };
 
+static struct inno_hdmi_phy_config rk3036_hdmi_phy_configs[] = {
+   {  7425, 0x3f, 0xbb },
+   { 16500, 0x6f, 0xbb },
+   {  ~0UL, 0x00, 0x00 }
+};
+
+static int inno_hdmi_find_phy_config(struct inno_hdmi *hdmi,
+unsigned long pixelclk)
+{
+   const struct inno_hdmi_phy_config *phy_configs =
+   hdmi->variant->phy_configs;
+   int i;
+
+   for (i = 0; phy_configs[i].pixelclock != ~0UL; i++) {
+   if (pixelclk <= phy_configs[i].pixelclock)
+   return i;
+   }
+
+   DRM_DEV_DEBUG(hdmi->dev, "No phy configuration for pixelclock %lu\n",
+ pixelclk);
+
+   return -EINVAL;
+}
+
 static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset)
 {
return readl_relaxed(hdmi->regs + (offset) * 0x04);
@@ -164,12 +201,25 @@ static void inno_hdmi_standby(struct inno_hdmi *hdmi)
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
 };
 
-static void inno_hdmi_power_up(struct inno_hdmi *hdmi)
+static void inno_hdmi_power_up(struct inno_hdmi *hdmi,
+  unsigned long mpixelclock)
 {
+   struct inno_hdmi_phy_config *phy_config;
+   int ret = inno_hdmi_find_phy_config(hdmi, mpixelclock);
+
+   if (ret < 0) {
+   phy_config = hdmi->variant->default_phy_config;
+   DRM_DEV_ERROR(hdmi->dev,
+ "Using default phy configuration for TMDS rate 
%lu",
+ mpixelclock);
+   } else {
+   phy_config = >variant->phy_configs[ret];
+   }
+
inno_hdmi_sys_power(hdmi, false);
 
-   hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
-   hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
+   hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, phy_config->pre_emphasis);
+   hdmi_writeb(hdmi, HDMI_PHY_DRIVER, phy_config->voltage_level_control);
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
@@ -406,6 +456,7 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
   struct drm_display_mode *mode)
 {
struct drm_display_info *display = >connector.display_info;
+   unsigned long mpixelclock = mode->clock * 1000;
 
/* Mute video and audio output */
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
@@ -428,13 +479,13 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
 * clock rate, and reconfigure the DDC clock.
 */
-   inno_hdmi_i2c_init(hdmi, mode->clock * 1000);
+   inno_hdmi_i2c_init(hdmi, mpixelclock);
 
/* Unmute video and audio output */
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
  v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
 
-   inno_hdmi_power_up(hdmi);
+   inno_hdmi_power_up(hdmi, mpixelclock);
 
return 0;
 }
@@ -821,6 +872,7 @@ static int inno_hdmi_bind(struct device *dev, struct device 
*master,
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = data;
struct inno_hdmi *hdmi;
+   const struct inno_hdmi_variant *variant;
int irq;
int ret;
 
@@ -830,6 +882,12 @@ static int inno_hdmi_bind(struct device *dev, struct 
device *master,
 
hdmi->dev = dev;
 
+   variant = 

[PATCH v3 13/29] drm/rockchip: inno_hdmi: Drop HDMI Vendor Infoframe support

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

The HDMI vendor infoframe is only meant to be sent with 4k60 modes and
higher, but the controller doesn't support them. Let's drop them from
the kernel.

Suggested-by: Johan Jonker 
Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - added my SoB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 35 
 1 file changed, 10 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 102195837206..5c9f1325441f 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -206,11 +206,15 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
 }
 
 static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
- union hdmi_infoframe *frame, u32 frame_index,
- u32 mask, u32 disable, u32 enable)
+ union hdmi_infoframe *frame, u32 frame_index)
 {
-   if (mask)
-   hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable);
+   struct drm_connector *connector = >connector;
+
+   if (frame_index != INFOFRAME_AVI) {
+   drm_err(connector->dev,
+   "Unsupported infoframe type: %u\n", frame_index);
+   return 0;
+   }
 
hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
 
@@ -226,28 +230,11 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, 
int setup_rc,
for (i = 0; i < rc; i++)
hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
packed_frame[i]);
-
-   if (mask)
-   hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable);
}
 
return setup_rc;
 }
 
-static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi,
- struct drm_display_mode *mode)
-{
-   union hdmi_infoframe frame;
-   int rc;
-
-   rc = drm_hdmi_vendor_infoframe_from_display_mode(,
->connector,
-mode);
-
-   return inno_hdmi_upload_frame(hdmi, rc, , INFOFRAME_VSI,
-   m_PACKET_VSI_EN, v_PACKET_VSI_EN(0), v_PACKET_VSI_EN(1));
-}
-
 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
  struct drm_display_mode *mode)
 {
@@ -265,7 +252,7 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi 
*hdmi,
else
frame.avi.colorspace = HDMI_COLORSPACE_RGB;
 
-   return inno_hdmi_upload_frame(hdmi, rc, , INFOFRAME_AVI, 0, 0, 0);
+   return inno_hdmi_upload_frame(hdmi, rc, , INFOFRAME_AVI);
 }
 
 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
@@ -408,10 +395,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 
inno_hdmi_config_video_csc(hdmi);
 
-   if (display->is_hdmi) {
+   if (display->is_hdmi)
inno_hdmi_config_video_avi(hdmi, mode);
-   inno_hdmi_config_video_vsi(hdmi, mode);
-   }
 
/*
 * When IP controller have configured to an accurate video
-- 
2.43.0



[PATCH v3 09/29] drm/rockchip: inno_hdmi: Remove unneeded has audio flag

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

The sink_has_audio flag is not used anywhere in the driver so let's get
rid of it. It's redundant with drm_display_info.has_audio anyway.

Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - added my SoB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index d99896f1a73a..58aff7a9c09a 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -28,7 +28,6 @@
 #include "inno_hdmi.h"
 
 struct hdmi_data_info {
-   bool sink_has_audio;
unsigned int enc_in_format;
unsigned int enc_out_format;
unsigned int colorimetry;
@@ -554,7 +553,6 @@ static int inno_hdmi_connector_get_modes(struct 
drm_connector *connector)
 
edid = drm_get_edid(connector, hdmi->ddc);
if (edid) {
-   hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid);
drm_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
kfree(edid);
-- 
2.43.0



[PATCH v3 11/29] drm/rockchip: inno_hdmi: Remove YUV-based csc coefficents

2023-12-19 Thread Alex Bee
Now that the unneeded support for YUV based input formats is gone, the csc
coefficients for those formats can be dropped as well.

Signed-off-by: Alex Bee 
---
changes in v2:
 - new patch

changes in v3:
 - none

 drivers/gpu/drm/rockchip/inno_hdmi.c | 37 
 1 file changed, 37 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 7c75feedacad..04344ee1265d 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -74,49 +74,12 @@ static struct inno_hdmi *connector_to_inno_hdmi(struct 
drm_connector *connector)
 }
 
 enum {
-   CSC_ITU601_16_235_TO_RGB_0_255_8BIT,
-   CSC_ITU601_0_255_TO_RGB_0_255_8BIT,
-   CSC_ITU709_16_235_TO_RGB_0_255_8BIT,
CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
CSC_RGB_0_255_TO_RGB_16_235_8BIT,
 };
 
 static const char coeff_csc[][24] = {
-   /*
-* YUV2RGB:601 SD mode(Y[16:235], UV[16:240], RGB[0:255]):
-*   R = 1.164*Y + 1.596*V - 204
-*   G = 1.164*Y - 0.391*U - 0.813*V + 154
-*   B = 1.164*Y + 2.018*U - 258
-*/
-   {
-   0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc,
-   0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a,
-   0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02
-   },
-   /*
-* YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]):
-*   R = Y + 1.402*V - 248
-*   G = Y - 0.344*U - 0.714*V + 135
-*   B = Y + 1.772*U - 227
-*/
-   {
-   0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8,
-   0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87,
-   0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3
-   },
-   /*
-* YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]):
-*   R = 1.164*Y + 1.793*V - 248
-*   G = 1.164*Y - 0.213*U - 0.534*V + 77
-*   B = 1.164*Y + 2.115*U - 289
-*/
-   {
-   0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8,
-   0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d,
-   0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21
-   },
-
/*
 * RGB2YUV:601 SD mode:
 *   Cb = -0.291G - 0.148R + 0.439B + 128
-- 
2.43.0



[PATCH v3 06/29] drm/rockchip: inno_hdmi: Switch encoder hooks to atomic

2023-12-19 Thread Alex Bee
From: Maxime Ripard 

The inno_hdmi encoder still uses the !atomic variants of enable, disable
and modeset. Convert to their atomic equivalents.

Signed-off-by: Maxime Ripard 
Tested-by: Alex Bee 
Signed-off-by: Alex Bee 
---
changes in v2:
 - imported patch

changes in v3:
 - added my SoB

 drivers/gpu/drm/rockchip/inno_hdmi.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c 
b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 14d2ba92a606..48c4f010b260 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -491,22 +491,25 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 }
 
 static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
-  struct drm_display_mode *mode,
-  struct drm_display_mode *adj_mode)
+  struct drm_crtc_state *crtc_state,
+  struct drm_connector_state *conn_state)
 {
+   struct drm_display_mode *adj_mode = _state->adjusted_mode;
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
 
inno_hdmi_setup(hdmi, adj_mode);
 }
 
-static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
+static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
+struct drm_atomic_state *state)
 {
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
 
inno_hdmi_set_pwr_mode(hdmi, NORMAL);
 }
 
-static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
+static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
+ struct drm_atomic_state *state)
 {
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
 
@@ -527,10 +530,10 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder 
*encoder,
 }
 
 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
-   .enable = inno_hdmi_encoder_enable,
-   .disable= inno_hdmi_encoder_disable,
-   .mode_set   = inno_hdmi_encoder_mode_set,
-   .atomic_check = inno_hdmi_encoder_atomic_check,
+   .atomic_check   = inno_hdmi_encoder_atomic_check,
+   .atomic_enable  = inno_hdmi_encoder_enable,
+   .atomic_disable = inno_hdmi_encoder_disable,
+   .atomic_mode_set= inno_hdmi_encoder_mode_set,
 };
 
 static enum drm_connector_status
-- 
2.43.0



  1   2   >