Indeed if you convert the text string to codepoints and the codepoints back to a string the newlines are present. I’m not sure understand why they don’t show up otherwise.
It’s the HTML rendering that suppresses newlines. You can add them server-side…
let $value := request:parameter($p) return <tr><td>{ for $line in tokenize($value, char('\n')) return ($line, <br/>) }</td><td>
…or return the result inside a pre tag:
<td><pre>{ request:parameter($p) }</pre></td>